Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. memory device context coordinates

memory device context coordinates

Scheduled Pinned Locked Moved C / C++ / MFC
graphicsperformancequestion
8 Posts 3 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • A Offline
    A Offline
    Alexander Kindel
    wrote on last edited by
    #1

    I'm working on a music notation program, where it needs to be possible to select any object, like a note or a clef, by clicking on the glyph. In order to determine whether a glyph has been clicked, I'm trying the approach of iterating through the drawable objects, rendering them each into a memory device context with a blank bitmap selected, mapping the mouse coordinates into this bitmap, and checking whether the pixel they map to is filled. While I'm getting this system working, I'm rendering a rectangular frame with the dimensions of the memory device context's bitmap to the corner of the window, and rendering the bitmap itself into it using BitBlt in order to see what's going on. What I see surprises me. I thought that rendering a glyph into the memory device context using TextOutW with x = 0 and y = 0 would put the glyph's origin at the top left of the bitmap, like it does when rendering to a window in the most basic case. Instead, the glyph appears to the left but vertically centered in the frame. So...given that the bitmap handle I selected into the memory device context was created using CreateCompatibleBitmap with cx = w and cy = h, does TextOutW treat it as having a coordinate system where x ranges from 0 to w while y ranges from -h/2 to h/2? Is there somewhere on MSDN that discusses this?

    M L A 3 Replies Last reply
    0
    • A Alexander Kindel

      I'm working on a music notation program, where it needs to be possible to select any object, like a note or a clef, by clicking on the glyph. In order to determine whether a glyph has been clicked, I'm trying the approach of iterating through the drawable objects, rendering them each into a memory device context with a blank bitmap selected, mapping the mouse coordinates into this bitmap, and checking whether the pixel they map to is filled. While I'm getting this system working, I'm rendering a rectangular frame with the dimensions of the memory device context's bitmap to the corner of the window, and rendering the bitmap itself into it using BitBlt in order to see what's going on. What I see surprises me. I thought that rendering a glyph into the memory device context using TextOutW with x = 0 and y = 0 would put the glyph's origin at the top left of the bitmap, like it does when rendering to a window in the most basic case. Instead, the glyph appears to the left but vertically centered in the frame. So...given that the bitmap handle I selected into the memory device context was created using CreateCompatibleBitmap with cx = w and cy = h, does TextOutW treat it as having a coordinate system where x ranges from 0 to w while y ranges from -h/2 to h/2? Is there somewhere on MSDN that discusses this?

      M Offline
      M Offline
      mo1492
      wrote on last edited by
      #2

      I might not be getting the full scope of your question but since you are drawing the glyphs into I assume 'known' rectangle area, could you not use CRect::PtInRect() to test if you hit a glyph area?

      A 1 Reply Last reply
      0
      • M mo1492

        I might not be getting the full scope of your question but since you are drawing the glyphs into I assume 'known' rectangle area, could you not use CRect::PtInRect() to test if you hit a glyph area?

        A Offline
        A Offline
        Alexander Kindel
        wrote on last edited by
        #3

        I want the clickable area to be exactly the pixels that are part of the glyph, rather than anywhere in a bounding rectangle that contains the glyph. There are situations where music symbols nest together, or where parts of one are visible through the gaps in another. Using single rectangles for each would count one as obscuring parts of the other even though those parts are visible - any part that's visible should be clickable. I could define a set of bounding rectangles for each glyph in order to approximate them more tightly, but that's a lot of work I'd rather not do unless it turns out that the method I describe is too slow.

        1 Reply Last reply
        0
        • A Alexander Kindel

          I'm working on a music notation program, where it needs to be possible to select any object, like a note or a clef, by clicking on the glyph. In order to determine whether a glyph has been clicked, I'm trying the approach of iterating through the drawable objects, rendering them each into a memory device context with a blank bitmap selected, mapping the mouse coordinates into this bitmap, and checking whether the pixel they map to is filled. While I'm getting this system working, I'm rendering a rectangular frame with the dimensions of the memory device context's bitmap to the corner of the window, and rendering the bitmap itself into it using BitBlt in order to see what's going on. What I see surprises me. I thought that rendering a glyph into the memory device context using TextOutW with x = 0 and y = 0 would put the glyph's origin at the top left of the bitmap, like it does when rendering to a window in the most basic case. Instead, the glyph appears to the left but vertically centered in the frame. So...given that the bitmap handle I selected into the memory device context was created using CreateCompatibleBitmap with cx = w and cy = h, does TextOutW treat it as having a coordinate system where x ranges from 0 to w while y ranges from -h/2 to h/2? Is there somewhere on MSDN that discusses this?

          L Offline
          L Offline
          leon de boer
          wrote on last edited by
          #4

          You are dealing with TTF glyphs not a bitmap and you will need to understand how FUnits and the EMSquare work TrueType fundamentals - Typography | Microsoft Docs[^] The glyph is rendered to screen it never is a bitmap. Now what you could do if font style isn't important is select a bitmap font and it will work much as you think. Now if you want to do what you are doing with a TTF the function you want is called GetGlyphOutlineA function | Microsoft Docs[^] The DC will be your window you are drawing the text on so it matches one to one. Now the problem is you will have an outline with beziers and lines and to be able to decide if you are in or out you need to scanline the contour at the y value and see if the point is between any two runline points of the scanline. Now if you follow all that this is the two scanline functions you need

          /*-ScanlineLine2D-----------------------------------------------------------
          Scanline (sy) intersect and the line between the two vertices. The return
          will be 0 for no intersect or 1 and px will contain x intersect value.
          A horizontal line on the scan line will return no points as is consistant
          with scan lining.
          ---------------------------------------------------------------------------*/
          short ScanlineLine2D(long x1, long y1, // Vertex 1 (x1,y1)
          long x2, long y2, // Vertex 2 (x2,y2)
          long sy, // Scan line y value
          long* px1){ // X interection pt
          long xt;
          double t;

          if (y2 == y1) return (0);										// Trivial fail horizontal line even if coincides with sy
          if (((sy >= y1) && (sy <= y2)) || ((sy >= y2) && (sy <= y1))){	// Check sy within range between y1 and y2
          	
          	// yt = (y2-y1)\*t + y1		where 0 <= t <= 1, 
          	// Re-arranging  t = (yt - y1)/(y2-y1)
          	// Our yt value will be sy-epsilon so we don't get single corner points
          	// t = ((sy-epsilon) - y1)/(y2-y1)
          	// Re-arranging for floats   t = ((sy-y1)-epsilon)/(y2-y1)
          	t = ((double)(sy-y1)-FLT\_EPSILON)/(double)(y2-y1);		// Calculate t value
          
          	if ( (t >= 0.0) && (t <= 1.0)) {				// Che
          
          A 1 Reply Last reply
          0
          • L leon de boer

            You are dealing with TTF glyphs not a bitmap and you will need to understand how FUnits and the EMSquare work TrueType fundamentals - Typography | Microsoft Docs[^] The glyph is rendered to screen it never is a bitmap. Now what you could do if font style isn't important is select a bitmap font and it will work much as you think. Now if you want to do what you are doing with a TTF the function you want is called GetGlyphOutlineA function | Microsoft Docs[^] The DC will be your window you are drawing the text on so it matches one to one. Now the problem is you will have an outline with beziers and lines and to be able to decide if you are in or out you need to scanline the contour at the y value and see if the point is between any two runline points of the scanline. Now if you follow all that this is the two scanline functions you need

            /*-ScanlineLine2D-----------------------------------------------------------
            Scanline (sy) intersect and the line between the two vertices. The return
            will be 0 for no intersect or 1 and px will contain x intersect value.
            A horizontal line on the scan line will return no points as is consistant
            with scan lining.
            ---------------------------------------------------------------------------*/
            short ScanlineLine2D(long x1, long y1, // Vertex 1 (x1,y1)
            long x2, long y2, // Vertex 2 (x2,y2)
            long sy, // Scan line y value
            long* px1){ // X interection pt
            long xt;
            double t;

            if (y2 == y1) return (0);										// Trivial fail horizontal line even if coincides with sy
            if (((sy >= y1) && (sy <= y2)) || ((sy >= y2) && (sy <= y1))){	// Check sy within range between y1 and y2
            	
            	// yt = (y2-y1)\*t + y1		where 0 <= t <= 1, 
            	// Re-arranging  t = (yt - y1)/(y2-y1)
            	// Our yt value will be sy-epsilon so we don't get single corner points
            	// t = ((sy-epsilon) - y1)/(y2-y1)
            	// Re-arranging for floats   t = ((sy-y1)-epsilon)/(y2-y1)
            	t = ((double)(sy-y1)-FLT\_EPSILON)/(double)(y2-y1);		// Calculate t value
            
            	if ( (t >= 0.0) && (t <= 1.0)) {				// Che
            
            A Offline
            A Offline
            Alexander Kindel
            wrote on last edited by
            #5

            I was actually able to make what I originally had in mind work - I know the glyphs aren't *defined* as bitmaps, but rendering a glyph into a device context with a bitmap selected effectively makes it into it into a bitmap, and that's what I did - but analyzing the glyph outlines directly as you suggest is surely more efficient, so I'll probably try it too.

            L 1 Reply Last reply
            0
            • A Alexander Kindel

              I'm working on a music notation program, where it needs to be possible to select any object, like a note or a clef, by clicking on the glyph. In order to determine whether a glyph has been clicked, I'm trying the approach of iterating through the drawable objects, rendering them each into a memory device context with a blank bitmap selected, mapping the mouse coordinates into this bitmap, and checking whether the pixel they map to is filled. While I'm getting this system working, I'm rendering a rectangular frame with the dimensions of the memory device context's bitmap to the corner of the window, and rendering the bitmap itself into it using BitBlt in order to see what's going on. What I see surprises me. I thought that rendering a glyph into the memory device context using TextOutW with x = 0 and y = 0 would put the glyph's origin at the top left of the bitmap, like it does when rendering to a window in the most basic case. Instead, the glyph appears to the left but vertically centered in the frame. So...given that the bitmap handle I selected into the memory device context was created using CreateCompatibleBitmap with cx = w and cy = h, does TextOutW treat it as having a coordinate system where x ranges from 0 to w while y ranges from -h/2 to h/2? Is there somewhere on MSDN that discusses this?

              A Offline
              A Offline
              Alexander Kindel
              wrote on last edited by
              #6

              The reason the location of the glyph in the memory device context bitmap wasn't what I had expected was that I had long ago set the text alignment of the window device context to TA_BASELINE, but that of the newly-created memory device context was set to something else.

              L 1 Reply Last reply
              0
              • A Alexander Kindel

                I was actually able to make what I originally had in mind work - I know the glyphs aren't *defined* as bitmaps, but rendering a glyph into a device context with a bitmap selected effectively makes it into it into a bitmap, and that's what I did - but analyzing the glyph outlines directly as you suggest is surely more efficient, so I'll probably try it too.

                L Offline
                L Offline
                leon de boer
                wrote on last edited by
                #7

                Throw me an email to my personal account if you need a help. I have a pile of code for this stuff from CNC programs I have worked on for filling and inline/outlining the TTF fonts.

                In vino veritas

                1 Reply Last reply
                0
                • A Alexander Kindel

                  The reason the location of the glyph in the memory device context bitmap wasn't what I had expected was that I had long ago set the text alignment of the window device context to TA_BASELINE, but that of the newly-created memory device context was set to something else.

                  L Offline
                  L Offline
                  leon de boer
                  wrote on last edited by
                  #8

                  It always defaults to TA_TEXT

                  In vino veritas

                  1 Reply Last reply
                  0
                  Reply
                  • Reply as topic
                  Log in to reply
                  • Oldest to Newest
                  • Newest to Oldest
                  • Most Votes


                  • Login

                  • Don't have an account? Register

                  • Login or register to search.
                  • First post
                    Last post
                  0
                  • Categories
                  • Recent
                  • Tags
                  • Popular
                  • World
                  • Users
                  • Groups