Erasing text drawn thorugh ExtTextOut function - c++

I have a class derived from CStatic and on that i m painting lines to show measurement in MFC C++ project. The problem is that I m displaying the line's distance at round about the mid of the line. I m using ExtTextOut function to draw the text. As i m using device context for that, I googled alot to erase that text and redraw on some other location, but i m unable to do. Basically CStatic has an image display over which i m drawing for measurement. Please can anyone tell me how to erase the text drawn through ExtTextOut without harming the background image?
Thanks In advance

I don't think you can just erase the text, leaving what's behind it untouched. You have to redraw the background again.
If you don't want to redraw everything, you can invalidate the part where the text lies (with InvalidateRect or InvalidateRgn) and only that will be redrawn.
Another option, that works with lines but I don't know if it works with text, would be to set the drawing mode with CDC::SetROP2 to R2_XORPEN (I think), draw the text, then draw it again to erase it. By doing it this way, the text will look "mixed" with the background, though.

Related

How to detect mouse hover over a line plot in Qt?

I am new to C++,Qt and Visual Studio and this is my first post on Stack Overflow.
I apologize in advance if this is a repeated question, I tried searching for a similar question but couldn't find one. Let me know if this is a repeated question and I will delete it.
I am trying to create a line plot using QWidget::paintEvent(). The line plot I am drawing is actually a QPainterPath. I want to detect when the mouse hovers over my line plot and so I create a small rectangle where my mouse cursor is and detect when this rectangle intersects with my line plot using bool QPainterPath::intersects() function. The problem is that this function returns true even when my mouse is not exactly over my line plot. In the Image 1 (I am not allowed to embed images yet) my line plot is the thick black curve and the bool QPainterPath::intersects() returns true even when my cursor is over the yellow region. As per the Qt document this is because:
There is an intersection if any of the lines making up the rectangle crosses a part of the path or if any part of the rectangle overlaps with any area enclosed by the path.
There is no way to have a QPainterPath without any enclosed area as Qt only provides two types of fill for QPainterPath: Qt::OddEvenFill or Qt::WindingFill. (To be honest, I find this kind of annoying, since an open path is a series of line segments connected end-to-end, if someone wants to enclose an area they can easily connect the first and last point using either QPainterPath::lineTo() or QPainterPath::moveTo() functions)
Anyway, I decided to get smarter than Qt and drew two extra QPainterPath with pathUp being a few pixels above my line plot and pathDn being a few pixels below my line plot. Image 2 shows these 3 line plots, red one is pathUp, black one is real line plot and green one is pathDn. I thought I coould detect the intersection in the QWidget::mouseMoveEvent() by using the following code:
// cRect: Rectangle at mouse cursor position
if((pathUp.intersects(cRect) && (!pathDn.intersects(cRect))) || ((!pathUp.intersects(cRect)) && pathDn.intersects(cRect)))
{
qDebug() << "Intersects";
}
But this still produces wrong results because now the enclosed area is different, as you can see in Image 3 the green area is an enclosed area of pathDn and red area is the enclosed area of pathUp. The thick black curve is again the line plot that I want to detect my mouse hover on. This enclosed area is not affected by Qt::setFillRule of QPainterPath.
What's even more frustrating is that I tried this technique using QPolygonF instead of QPainterPath on QWidget and the results were exactly the same. I also tried QGraphicsView, there I used QGraphicsPathItem to create my line plot and then used QGraphicsScene::focusItemChanged() signal to detect when I click on my line plot. It again produced the same result of detecting the click when my cursor is over the enclosed area. I do not want to create a custom QGraphicsItem (unless I absolutely have to) just to reimplement it's hoverEnterEvent() and hoverLeaveEvent() method because of the limitations imposed on the boundingRect() of the QGraphicsItem as explained in Qt Docs:
QGraphicsScene expects all items boundingRect() and shape() to remain unchanged unless it is notified. If you want to change an item's geometry in any way, you must first call prepareGeometryChange() to allow QGraphicsScene to update its bookkeeping.
Since I making a plot in real-time the boundingRect() will change quite frequently (> 20 Hz), which will result in an extra computational burden on the software. Is there any way I can solve my problem without creating a custom QGraphicsItem?
P.S. I have been using Stack Overflow for many years whenever I got stuck. I just never made an account here because I never needed to post anything. You guys are the best and I am very happy to be a part of this community!

Text deleted by backspace is not being updated on my arduino tft display (adafruit gfx library)

For university, we need to make a game in Unity that is controlled with an Arduino. My idea was a hacking game where the Arduino acts as the 'hacking device' when hacking something in the game. The arduino would have a screen and on that screen would be a basic command-line interface that lets me input simple commands to 'hack' but I've been having trouble regarding text and clearing it.
I've been able to use unity to send typed characters to the display as-well as a backspace function (pressing backspace would remove last character in the string)
I first had issue with clearing all the text when writing (calling tft.print doesn't clear any previous text). I was using fillScreen which was slow. I found out setTextColor had a second argument that let me just set all certain colored text to a different color. Setting it to black would essentially clear it.
This made it update pretty much instantly when writing to the screen but I now had a new issue, backspace would no longer would.
My understand is that when removing the character, it's color won't be updated when calling setTextColor leaving it on the screen until a restart/fillScreen is called.
I'm not really sure how to solve this and all google searches turn up little to no help.
Here's my code for updating the text:
void updateString(char c){
tft.setTextColor(WHITE,BLACK);
if(c!='<'){
//Add new character to end of string
str.concat(String(c));
}
else if(c=='<' && str.length()>2){
//Remove last character in string
str.remove(str.length()-1);
}
//Set cursor back to 0,0
tft.setCursor(0,0);
//Display text
tft.print(str);
}
I'd appreciate any help.
Maybe, use a similar function to tft.clear() each time you refresh the screen or you can draw a filled square of the background on the text so it looks like it has been erased then you rewrite the text.
Sounds like you are using proportionally-spaced fonts instead of the original classic fonts that ships with Adafruit_GFX. Historically, when using the default classic fonts one could set the background color option of the text to the same color as the background of the screen (usually black). This would overwrite the old screen contents with new data and work because the characters using the classic fonts are a uniform size. When using proportionally-spaced fonts, the background color option for the font is disabled by design.
This was presumably because of memory requirements and speed on slower AVR's. Regardless, when using proportionally-spaced fonts the background color feature won't work due to non-uniform sized characters overlapping the same regions as adjacent characters.
There are two work-arounds to this. Adafruit says in order to replace previously drawn text when using custom fonts you can either:
Use getTextBounds() to determine the smallest rectangle that encloses a
string and then erase that area using fillRect() prior to drawing
the new text. OR
Create an offscreen bitmap using GFXcanvas1 for a fixed size area,
draw the text in the GFXcanvas1 object and then copy to the screen
using drawBitmap().
Note that options 1 & 2 above are mutually exclusive. The second method requires more memory. The first method isn't perfect and produces some small amount of flicker, but is in general acceptable if coded carefully.
I hope that I have understood what the nature of your problem is and answered it in a satisfactory manner. If nothing else, at least now you know why custom font's will not work with the so called background color feature that works with the original 'classic' Adafruit fonts.
Nikki Cooper

MITK Segmentation draw Rectangle

I have to segment a few things in a dataset I have (.nrrd-file) by drawing a rectangle around the area of interest and saving the segments (also as .nrrd-files).
I tried everything in the Segmentation-Tool that comes with MITK but I cannot seem to find a way to draw rectangles. I also tried to do some key combos (like holding shift, ctrl or alt) while drawing but in vain.
I know I can use the Measurement-Tool to select rectangles and save them (as .pf-files), but using that I'd have to write a some code to convert those selected rectangles into rectangle segmentations later on.
Does anyone know whether there's a possibility (that I didnt find yet) to draw rectangles in the Segmentation tool, or some other way so there's no need to write a workaround?
You can use the Image Cropper plugin in MITK 2016.11 for rectangular image masking and cropping (scissors icon).
Open the plugin, select your image in the Data Manager and click on the New button in the plugin to create a bounding object. You can modify the rectangular bounding shape in the render windows by dragging its red handles. You can move the whole shape by hovering over the bounding shape (it will turn green), click, and than drag.
Click on the Mask button if you want to get an image with the same dimensions in which all pixels outside the bounding shape are set to a user defined value (see the Advanced settings in the plugin). Click on the Crop button otherwise.
Note that you can always press F1 in any active MITK plugin to open a help page with detailed instructions.

Colored border of the transparent color key around text written on the transparent window

I created a Transparent Layered window with a color key that I use to make the window transparent.
So far it works all fine.
Writing text on it - using GDI+ - works, too...
The problem I encounter is, that the text has a thin border of the colorkey-color around the letters...
What I do in the WM_PAINT is:
1. Clear the drawing area Graphics::Clear(ColorKey);
2. Draw the text on it.
Screenshot of what i mean: http://imageshack.us/photo/my-images/709/cutp.jpg/
Anyone knows about how to avoid this?
Try calling Graphics::SetTextRenderingHint(TextRenderingHintSingleBitPerPixelGridFit).

What are useful functions for drawing text (MFC)?

I'm creating a line chart control, and I need to write (or better say draw) the axis names and axis values.
I found DrawText and TextOut functions, but the text they show is flickering and don't know how to set the font and text orientation (I will need vertical text orientation as well as horizontal).
Are there any other functions you could recommend or how to use these stated above and get the results I need?
I doubt the flickering is caused by DrawText or TextOut, but rather your paint method. If you are redrawing the entire window on the paint event it is likely to flcker as you erase the whole window, and then there is a perceptible delay before all elements are redrawn.
It may be possible to reduce the flicker acceptably by only painting the invalidated region; however this can become complex. A simpler method is to use double buffering; where you draw to a non-visible memory context, and then switch it to visible context.
Try Google'ing "MFC double buffering" for plenty of examples.
It sounds like you are looking for CMemDC, which basically wraps your CDC (or CPaintDC). You do all your drawing to the CMemDC, it then copies itself to your original CDC when destructed.
http://www.codeproject.com/KB/GDI/flickerfree.aspx
Btw, Visual Studio 2010 has add this class to the latest MFC:
http://msdn.microsoft.com/en-us/library/cc308997.aspx
Font & orientation you can set by doing GetLogFont(), modifying the LOGFONT members and then doing a CreateFontIndirect() with the modified settings. This is all win32 stuff with a very thin wrapper really, so you can read the Petzold to get details and more examples.