Text corrupted on TStatusBar while setting style to "OwnerDraw" - c++builder

I used TStatusBar and set style to "psOwnerDraw" to fill custom color on it.
There is no problem to display text in normal case but after I changed the resolution on Windows or moved application out of screen and back, the text is corrupted with some other text.
Here's my code:
void __fastcall TMainForm::TotalStatusBarDrawPanel(TStatusBar * StatusBar,
TStatusPanel * Panel, const TRect & Rect)
{
TRect StatusFillRect = Rect;
TCanvas& pCan = *StatusBar->Canvas;
if (Panel->Index == 0)
{
pCan.Font->Color = clRed;
pCan.Brush->Color = clBtnFace;
}
pCan.FillRect(StatusFillRect);
DrawTextW(pCan.Handle, Panel->Text.c_str(), -1,
&StatusFillRect, DT_SINGLELINE | DT_VCENTER);
}

Related

How to use custom fonts in gocv library

I want to add a text on an given co-ordinates of an image using the gocv library (also the text should expand from the co-ordinates; not from left to right).
Using the below command I was able to achieve both requirements. How can I load a custom .ttf font file and do the same thing ?
import (
"fmt"
"image"
"image/color"
"os"
"github.com/gofiber/fiber/v2"
"gocv.io/x/gocv"
)
func GeneralRoutes(gen fiber.Router) {
gen.Get("/image", func(c *fiber.Ctx) error {
imageFile := "path/input.png"
outputFile := "path/output.jpg"
img := gocv.IMRead(imageFile, gocv.IMReadColor)
if img.Empty() {
fmt.Printf("Error opening image: %s\n", imageFile)
os.Exit(1)
}
// Create a font type and scale
font := gocv.FontHersheyPlain
scale := 5.5
thickness := 5
// Define the text to be added, position, font type and color
text := "Hello World"
textSize := gocv.GetTextSize(text, font, scale, thickness)
textPos := img.Point{X: 1170 - textSize.X/2, Y: 663 - textSize.Y/2}
gocv.PutText(&img, text, textPos, font, scale, color.RGBA{0, 0, 0, 0}, thickness)
// Save the output image
gocv.IMWrite(outputFile, img)
return c.SendFile(outputFile)
})
}

using tablet pen on the whiteboard

I'm making a digital whiteboard program with C++Builder.
It draws lines on a TImage using MouseDown and MouseMove events, like this:
Image1->Picture->Bitmap->Canvas->LineTo(x, y);
There is no problem when using the mouse.
However, when I use a Wacom tablet to draw the line, it doesn't fully recognize the movement of the pen. The problem occurs more when writing than when drawing a figure on the whiteboard.
I have no idea how to solve this problem.
What is the cause of the problem? How can I solve it?
Attached is the captured one to help you understand the problem. Same is written with mouse on the left side, and tablet pen on right side.
Code is like this:
void __fastcall TForm1::Image1MouseDown(TObject *Sender,
TMouseButton Button, TShiftState Shift, int X, int Y)
{
MouseClick = true;
Image1->Picture->Bitmap->Canvas->MoveTo(X,Y);
Image1->Picture->Bitmap->Canvas->LineTo(X,Y);
if (Pen==1){
if(type==0) //pen
{
Image1->Picture->Bitmap->Canvas->Pen->Color = ColorDialog1->Color;
PenColor = ColorDialog1->Color;
}
else if(type==1) //eraser
{
Image1->Picture->Bitmap->Canvas->Pen->Color = clWhite;
PenColor = clWhite;
}
Image1->Picture->Bitmap->Canvas->Pen->Width = ScrollBar1->Position;
PenWidth = ScrollBar1->Position;
}
}
//--------------------------------------------------------------------------
void __fastcall TForm1::Image1MouseMove(TObject *Sender,
TShiftState Shift, int X, int Y)
{
if(MouseClick)
{
Image1->Picture->Bitmap->Canvas->LineTo(X,Y);
}
}

Why is getWindowImageRect in OpenCV for Windows does not return the expected value?

I was trying to make a fullscreen window in OpenCV and the functions provided in OpenCV are working except there is a white edge in the left border and top border. After spending time in investigating the code in OpenCV, I found out that the function getWindowImageRect is somehow returning a value that is 1px more in x, y and 1px less in width and height than the function that I have wrote.
Okay, and here is the question. Why are the two functions returning different values?
Here is the code I have found in OpenCV:
CvRect cvGetWindowRect_W32(const char* name)
{
CvRect result = cvRect(-1, -1, -1, -1);
CV_FUNCNAME( "cvGetWindowRect_W32" );
__BEGIN__;
CvWindow* window;
if (!name)
CV_ERROR( CV_StsNullPtr, "NULL name string" );
window = icvFindWindowByName( name );
if (!window)
EXIT; // keep silence here
RECT rect;
GetClientRect(window->hwnd, &rect);
{
POINT pt = {rect.left, rect.top};
ClientToScreen(window->hwnd, &pt);
result = cvRect(pt.x, pt.y, rect.right - rect.left, rect.bottom - rect.top);
}
__END__;
return result;
}
This is the code that I have wrote in Python, which I thought will give me the same result:
def getWindowRect(name)
hwnd = win32gui.FindWindow(None, name)
rect_l, rect_t, rect_r, rect_b = win32gui.GetClientRect(hwnd)
pt_x, pt_y = win32gui.ClientToScreen(hwnd, (rect_l, rect_t))
result = (pt_x, pt_y, rect_r - rect_l, rect_b - rect_t)
return result
The result of using the two above functions give me output like this:
(1, 1, 2559, 1439)
(0, 0, 2560, 1440)
So I wonder if any one can tell me why is this happening?
Note that the test is performed under Windows 10.

Update Widgets in PDF using Podofo

I am using PdfAnnotation.SetContents to set the value of an annotation.If the annotation is of type FreeText, only then this method correctly works and the value gets displayed on the PDF (using PDF Reader).If the type is Widget, the value gets set as content in pdf dictionary but does not get displayed.Is there a way i could set the value of a widget?
I found the solution, In order for the content to get displayed, an Appearance ("AP") Dictionary has to be set.
This could be used for that:
void PdfField::CreateFieldAppearance(PdfMemDocument *memDoc, const PdfString &value)
{
if( !m_pWidget->HasAppearanceStream() )
{
PdfRect pageRect;
PdfPainter painter;
PoDoFo::PdfRect rect = this->GetWidgetAnnotation()->GetRect();
unsigned int width = rect.GetWidth();
unsigned int height = rect.GetHeight();
PdfRect pdfRect(0, 0, width, height);
PdfXObject xObj(pdfRect, memDoc);
painter.SetPage(&xObj);
painter.SetClipRect(pdfRect);
painter.Save();
painter.SetColor(221.0/255.0, 228.0/255.0, 1.0);
painter.FillRect(0, 0, width, height);
painter.Restore();
// make rotation
painter.Save();
/***********************************************************************************/
// Rotation Logic
double angle = this->GetPage()->GetRotation();
if (angle) {
double radAngle = angle * M_PI / 180;
int cosA = (int)cos(radAngle);
int sinA = (int)sin(radAngle);
double translateY = rect.GetWidth(); // The View goes out of the bound, sits on top
painter.SetTransformationMatrix(cosA, sinA, -sinA, cosA, translateY, 0);
}
/***********************************************************************************/
PdfFont *font = memDoc->CreateFont("Helvetica", true, false);
font->SetFontSize(15);
// Do the drawing
painter.SetFont(font);
painter.BeginText(10, 5);
painter.SetStrokeWidth(20);
painter.AddText(value);
painter.EndText();
painter.FinishPage();
// This is very important. Not only does it disable the editing.
// Also it does correct the appearance issue on Adobe Readers.
this->SetReadOnly(true);
// The Stream Object has to be saved to the annotation
PoDoFo::PdfDictionary dict;
dict.AddKey( "N", xObj.GetObject()->Reference() );
this->GetFieldObject()->GetDictionary().AddKey( "AP", dict );
}
}

Paint to a bitmap using DirectX under Windows Metro

I am trying to use DirectX to create and paint into a bitmap, and then later use that bitmap to paint to the screen. I have the following test code which I have pieced together from a number of sources. I seem to be able to create the bitmap without errors, and I try and fill it with red. However, when I use the bitmap to paint to the screen I just get a black rectangle. Can anyone tell me what I might be doing wrong? Note that this is running as a Windows 8 Metro app, if that makes a difference.
Note that the formatter seems to be removing my angle brackets and I don't how stop it from doing that. The 'device' variable is of class ID3D11Device, the 'context' variable is ID3D11DeviceContext, the d2dContext variable is ID2D1DeviceContext, the dgixDevice variable is IDXGIDevice, and the 'd2dDevice' is ID2D1Device.
void PaintTestBitmap(GRectF& rect)
{
HRESULT hr;
UINT creationFlags = D3D11_CREATE_DEVICE_BGRA_SUPPORT;
D3D_FEATURE_LEVEL featureLevels[] =
{
D3D_FEATURE_LEVEL_11_1,
D3D_FEATURE_LEVEL_11_0,
D3D_FEATURE_LEVEL_10_1,
D3D_FEATURE_LEVEL_10_0,
D3D_FEATURE_LEVEL_9_3,
D3D_FEATURE_LEVEL_9_2,
D3D_FEATURE_LEVEL_9_1
};
ComPtr<ID3D11Device> device;
ComPtr<ID3D11DeviceContext> context;
ComPtr<ID2D1DeviceContext> d2dContext;
hr = D3D11CreateDevice( NULL,
D3D_DRIVER_TYPE_HARDWARE,
NULL,
creationFlags,
featureLevels,
ARRAYSIZE(featureLevels),
D3D11_SDK_VERSION,
&device,
NULL,
&context);
if (SUCCEEDED(hr))
{
ComPtr<IDXGIDevice> dxgiDevice;
device.As(&dxgiDevice);
// create D2D device context
ComPtr<ID2D1Device> d2dDevice;
hr = D2D1CreateDevice(dxgiDevice.Get(), NULL, &d2dDevice);
if (SUCCEEDED(hr))
{
hr = d2dDevice->CreateDeviceContext(D2D1_DEVICE_CONTEXT_OPTIONS_NONE, &d2dContext);
if (SUCCEEDED(hr))
{
ID2D1Bitmap1 *pBitmap;
D2D1_SIZE_U size = { rect.m_width, rect.m_height };
D2D1_BITMAP_PROPERTIES1 properties = {{ DXGI_FORMAT_R8G8B8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED }, 96, 96, D2D1_BITMAP_OPTIONS_TARGET, 0 };
hr = d2dContext->CreateBitmap(size, (const void *) 0, 0, &properties, &pBitmap);
if (SUCCEEDED(hr))
{
d2dContext->SetTarget(pBitmap);
d2dContext->BeginDraw();
d2dContext->Clear(D2D1::ColorF(D2D1::ColorF::Red)); // Clear the bitmap to Red
d2dContext->EndDraw();
// If I now use pBitmap to paint to the screen, I get a black rectange
// rather than the red one I was expecting
}
}
}
}
}
Note that I am fairly new to both DirectX and Metro style apps.
Thanks
what you're probably forgetting is that you dont draw your bitmap on your context.
what you can try is
hr = d2dContext->CreateBitmap(size, (const void *) 0, 0, &properties, &pBitmap);
if (SUCCEEDED(hr))
{
ID2D1Image *pImage = nullptr;
d2dContext->GetTarget(&image);
d2dContext->SetTarget(pBitmap);
d2dContext->BeginDraw();
d2dContext->Clear(D2D1::ColorF(D2D1::ColorF::Red)); // Clear the bitmap to Red
d2dContext->SetTarget(pImage);
d2dContext->DrawBitmap(pBitmap);
d2dContext->EndDraw();
}
what you do is store your rendertarget and then draw your bitmap and at the end you set your context to the right render target and let it draw your bitmap on it

Resources