My experience is mainly with OpenGL ES, which handles drawing textures differently, but the problem of pixel coordinates and NPOTS textures is shared. The problem can be solved relatively simply using a Texture wrapper class that determines if the graphics card supports NPOT textures and if it doesn't, creates an image at the next largest power of 2 at runtime, draws the base image into that image, then stores the scale necessary when drawing the image. As for pixel coordinates, that could also be solved in the Texture wrapper class.
Out of curiosity, do you do any optimization when drawing multiple frames from the same texture? On maps, for example, if all of the tiles are from one frameset which are all from one graphic sheet, all of the tiles could be draw in one draw call using glDrawElements. I suppose most of the time it's not too big an issue as far as speed is concerned, since it's only a 2-D game, but it's a potential bottleneck if you've got lots of tiles onscreen at the same time that could be remedied. I don't know if it would be easy or if it would require a lower-level change, like requiring tilesets to be defined as taking all tiles from one graphic sheet, or something. It could possibly be something you detect at compile time, whether to enable that method of drawing tiles or not, depending on where tiles are coming from.