mirror of
git://source.winehq.org/git/wine.git
synced 2024-09-01 09:33:37 +00:00
gdiplus: Added GdipDrawString.
This commit is contained in:
parent
059436d536
commit
f7d27e0020
|
@ -198,7 +198,7 @@
|
|||
@ stdcall GdipDrawRectangleI(ptr ptr long long long long)
|
||||
@ stdcall GdipDrawRectangles(ptr ptr ptr long)
|
||||
@ stub GdipDrawRectanglesI
|
||||
@ stub GdipDrawString
|
||||
@ stdcall GdipDrawString(ptr ptr long ptr ptr ptr ptr)
|
||||
@ stub GdipEmfToWmfBits
|
||||
@ stub GdipEndContainer
|
||||
@ stub GdipEnumerateMetafileDestPoint
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "winbase.h"
|
||||
#include "winuser.h"
|
||||
#include "wingdi.h"
|
||||
#include "wine/unicode.h"
|
||||
|
||||
#define COBJMACROS
|
||||
#include "objbase.h"
|
||||
|
@ -1270,6 +1271,141 @@ GpStatus WINGDIPAPI GdipDrawRectangles(GpGraphics *graphics, GpPen *pen,
|
|||
return Ok;
|
||||
}
|
||||
|
||||
GpStatus WINGDIPAPI GdipDrawString(GpGraphics *graphics, GDIPCONST WCHAR *string,
|
||||
INT length, GDIPCONST GpFont *font, GDIPCONST RectF *rect,
|
||||
GDIPCONST GpStringFormat *format, GDIPCONST GpBrush *brush)
|
||||
{
|
||||
HRGN rgn;
|
||||
HFONT gdifont;
|
||||
LOGFONTW lfw;
|
||||
TEXTMETRICW textmet;
|
||||
GpPointF pt[2], rectcpy[4];
|
||||
POINT corners[4];
|
||||
WCHAR* stringdup;
|
||||
REAL angle, ang_cos, ang_sin, rel_width, rel_height;
|
||||
INT sum = 0, height = 0, fit, fitcpy, save_state, i, j, lret, nwidth;
|
||||
SIZE size;
|
||||
|
||||
if(!graphics || !string || !font || !brush || !rect)
|
||||
return InvalidParameter;
|
||||
|
||||
if(format || (brush->bt != BrushTypeSolidColor)){
|
||||
FIXME("not implemented for given parameters\n");
|
||||
return NotImplemented;
|
||||
}
|
||||
|
||||
stringdup = GdipAlloc(length * sizeof(WCHAR));
|
||||
if(!stringdup) return OutOfMemory;
|
||||
|
||||
save_state = SaveDC(graphics->hdc);
|
||||
SetBkMode(graphics->hdc, TRANSPARENT);
|
||||
SetTextColor(graphics->hdc, brush->lb.lbColor);
|
||||
|
||||
rectcpy[3].X = rectcpy[0].X = rect->X;
|
||||
rectcpy[1].Y = rectcpy[0].Y = rect->Y;
|
||||
rectcpy[2].X = rectcpy[1].X = rect->X + rect->Width;
|
||||
rectcpy[3].Y = rectcpy[2].Y = rect->Y + rect->Height;
|
||||
transform_and_round_points(graphics, corners, rectcpy, 4);
|
||||
rel_width = sqrt((corners[1].x - corners[0].x) * (corners[1].x - corners[0].x) +
|
||||
(corners[1].y - corners[0].y) * (corners[1].y - corners[0].y))
|
||||
/ rect->Width;
|
||||
nwidth = roundr(rel_width * rect->Width);
|
||||
rel_height = sqrt((corners[2].x - corners[1].x) * (corners[2].x - corners[1].x) +
|
||||
(corners[2].y - corners[1].y) * (corners[2].y - corners[1].y))
|
||||
/ rect->Height;
|
||||
|
||||
rgn = CreatePolygonRgn(corners, 4, ALTERNATE);
|
||||
SelectClipRgn(graphics->hdc, rgn);
|
||||
|
||||
/* Use gdi to find the font, then perform transformations on it (height,
|
||||
* width, angle). */
|
||||
SelectObject(graphics->hdc, CreateFontIndirectW(&font->lfw));
|
||||
GetTextMetricsW(graphics->hdc, &textmet);
|
||||
memcpy(&lfw, &font->lfw, sizeof(LOGFONTW));
|
||||
|
||||
lfw.lfHeight = roundr(((REAL)lfw.lfHeight) * rel_height);
|
||||
lfw.lfWidth = roundr(textmet.tmAveCharWidth * rel_width);
|
||||
|
||||
pt[0].X = 0.0;
|
||||
pt[0].Y = 0.0;
|
||||
pt[1].X = 1.0;
|
||||
pt[1].Y = 0.0;
|
||||
GdipTransformMatrixPoints(graphics->worldtrans, pt, 2);
|
||||
angle = gdiplus_atan2((pt[1].Y - pt[0].Y), (pt[1].X - pt[0].X));
|
||||
ang_cos = cos(angle);
|
||||
ang_sin = sin(angle);
|
||||
lfw.lfEscapement = lfw.lfOrientation = -roundr((angle / M_PI) * 1800.0);
|
||||
|
||||
gdifont = CreateFontIndirectW(&lfw);
|
||||
DeleteObject(SelectObject(graphics->hdc, CreateFontIndirectW(&lfw)));
|
||||
|
||||
for(i = 0, j = 0; i < length; i++){
|
||||
if(!isprintW(string[i]) && (string[i] != '\n'))
|
||||
continue;
|
||||
|
||||
stringdup[j] = string[i];
|
||||
j++;
|
||||
}
|
||||
|
||||
stringdup[j] = 0;
|
||||
length = j;
|
||||
|
||||
while(sum < length){
|
||||
GetTextExtentExPointW(graphics->hdc, stringdup, length, nwidth,
|
||||
&fit, NULL, &size);
|
||||
fitcpy = fit;
|
||||
|
||||
if(fit == 0){
|
||||
TabbedTextOutW(graphics->hdc,
|
||||
corners[0].x + roundr(ang_sin * (REAL) height),
|
||||
corners[0].y + roundr(ang_cos * (REAL) height),
|
||||
stringdup + sum, 1, 0, 0, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
for(lret = 0; lret < fit; lret++)
|
||||
if(*(stringdup + sum + lret) == '\n')
|
||||
break;
|
||||
|
||||
/* Line break code (may look strange, but it imitates windows). */
|
||||
if(lret < fit)
|
||||
fit = lret; /* this is not an off-by-one error */
|
||||
else if(*(stringdup + sum + fit) == ' ')
|
||||
while(*(stringdup + sum + fit) == ' ')
|
||||
fit++;
|
||||
else
|
||||
while(*(stringdup + sum + fit - 1) != ' '){
|
||||
fit--;
|
||||
|
||||
if(*(stringdup + sum + fit) == '\t')
|
||||
break;
|
||||
|
||||
if(fit == 0){
|
||||
fit = fitcpy;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
TabbedTextOutW(graphics->hdc,
|
||||
corners[0].x - roundr(ang_sin * (REAL) height),
|
||||
corners[0].y + roundr(ang_cos * (REAL) height),
|
||||
stringdup + sum, min(length - sum, fit), 0, 0, 0);
|
||||
|
||||
sum += fit + (lret < fitcpy ? 1 : 0);
|
||||
height += size.cy;
|
||||
|
||||
if(height > roundr(rect->Height * rel_height))
|
||||
break;
|
||||
}
|
||||
|
||||
DeleteObject(rgn);
|
||||
DeleteObject(gdifont);
|
||||
|
||||
RestoreDC(graphics->hdc, save_state);
|
||||
|
||||
return Ok;
|
||||
}
|
||||
|
||||
GpStatus WINGDIPAPI GdipFillPath(GpGraphics *graphics, GpBrush *brush, GpPath *path)
|
||||
{
|
||||
INT save_state;
|
||||
|
|
|
@ -76,6 +76,9 @@ GpStatus WINGDIPAPI GdipDrawPath(GpGraphics*,GpPen*,GpPath*);
|
|||
GpStatus WINGDIPAPI GdipDrawPie(GpGraphics*,GpPen*,REAL,REAL,REAL,REAL,REAL,REAL);
|
||||
GpStatus WINGDIPAPI GdipDrawRectangleI(GpGraphics*,GpPen*,INT,INT,INT,INT);
|
||||
GpStatus WINGDIPAPI GdipDrawRectangles(GpGraphics*,GpPen*,GpRectF*,INT);
|
||||
GpStatus WINGDIPAPI GdipDrawString(GpGraphics*,GDIPCONST WCHAR*,INT,
|
||||
GDIPCONST GpFont*,GDIPCONST RectF*, GDIPCONST GpStringFormat*,
|
||||
GDIPCONST GpBrush*);
|
||||
GpStatus WINGDIPAPI GdipFillPath(GpGraphics*,GpBrush*,GpPath*);
|
||||
GpStatus WINGDIPAPI GdipFillPie(GpGraphics*,GpBrush*,REAL,REAL,REAL,REAL,REAL,REAL);
|
||||
GpStatus WINGDIPAPI GdipFillPolygonI(GpGraphics*,GpBrush*,GDIPCONST GpPoint*,INT,
|
||||
|
|
|
@ -37,6 +37,7 @@ class GpPathGradient : public GpBrush {};
|
|||
class GpLineGradient : public GpBrush {};
|
||||
class GpTexture : public GpBrush {};
|
||||
class GpFont {};
|
||||
class GpStringFormat {};
|
||||
|
||||
#else /* end of c++ declarations */
|
||||
|
||||
|
@ -56,6 +57,7 @@ typedef struct GpPathGradient GpPathGradient;
|
|||
typedef struct GpLineGradient GpLineGradient;
|
||||
typedef struct GpTexture GpTexture;
|
||||
typedef struct GpFont GpFont;
|
||||
typedef struct GpStringFormat GpStringFormat;
|
||||
|
||||
#endif /* end of c declarations */
|
||||
|
||||
|
|
Loading…
Reference in a new issue