summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorscuri <scuri>2010-06-12 22:00:54 +0000
committerscuri <scuri>2010-06-12 22:00:54 +0000
commit6cc4fd9f87137f98096cb53c6fbccd9e45b06d03 (patch)
tree3e432a79ef69b668829be362109d76178aa3e9cc /src
parentb96555cd065542fba0379750c87122e54f398313 (diff)
*** empty log message ***
Diffstat (limited to 'src')
-rw-r--r--src/cairo/cdcairo.c136
-rw-r--r--src/gdiplus/cdwinp.cpp34
2 files changed, 126 insertions, 44 deletions
diff --git a/src/cairo/cdcairo.c b/src/cairo/cdcairo.c
index 6ff389c..960a0d1 100644
--- a/src/cairo/cdcairo.c
+++ b/src/cairo/cdcairo.c
@@ -589,6 +589,33 @@ static long int cdforeground(cdCtxCanvas *ctxcanvas, long int color)
/******************************************************/
+static void sSetTransform(cdCtxCanvas *ctxcanvas, const double* matrix)
+{
+ if (matrix)
+ {
+ cairo_matrix_t mtx;
+
+ /* configure a bottom-up coordinate system */
+ mtx.xx = 1; mtx.yx = 0;
+ mtx.xy = 0; mtx.yy = -1;
+ mtx.x0 = 0; mtx.y0 = (ctxcanvas->canvas->h-1);
+ cairo_transform(ctxcanvas->cr, &mtx);
+
+ mtx.xx = matrix[0]; mtx.yx = matrix[1];
+ mtx.xy = matrix[2]; mtx.yy = matrix[3];
+ mtx.x0 = matrix[4]; mtx.y0 = matrix[5];
+ cairo_transform(ctxcanvas->cr, &mtx);
+ }
+ else if (ctxcanvas->rotate_angle)
+ {
+ /* rotation = translate to point + rotation + translate back */
+ /* the rotation must be corrected because of the Y axis orientation */
+ cairo_translate(ctxcanvas->cr, ctxcanvas->rotate_center_x, _cdInvertYAxis(ctxcanvas->canvas, ctxcanvas->rotate_center_y));
+ cairo_rotate(ctxcanvas->cr, (double)-ctxcanvas->rotate_angle * CD_DEG2RAD);
+ cairo_translate(ctxcanvas->cr, -ctxcanvas->rotate_center_x, -_cdInvertYAxis(ctxcanvas->canvas, ctxcanvas->rotate_center_y));
+ }
+}
+
static void cdclear(cdCtxCanvas* ctxcanvas)
{
cairo_save (ctxcanvas->cr);
@@ -763,10 +790,71 @@ static void cdbox(cdCtxCanvas *ctxcanvas, int xmin, int xmax, int ymin, int ymax
cdfbox(ctxcanvas, (double)xmin, (double)xmax, (double)ymin, (double)ymax);
}
+static void sGetTransformTextHeight(cdCanvas* canvas, int x, int y, int w, int h, int *hbox)
+{
+ int xmin, xmax, ymin, ymax;
+ int baseline, height, ascent;
+
+ /* distance from bottom to baseline */
+ cdgetfontdim(canvas->ctxcanvas, NULL, &height, &ascent, NULL);
+ baseline = height - ascent;
+
+ /* move to bottom-left */
+ cdTextTranslatePoint(canvas, x, y, w, h, baseline, &xmin, &ymin);
+
+ xmax = xmin + w-1;
+ ymax = ymin + h-1;
+
+ if (canvas->text_orientation)
+ {
+ double cos_theta = cos(canvas->text_orientation*CD_DEG2RAD);
+ double sin_theta = sin(canvas->text_orientation*CD_DEG2RAD);
+ int rectY[4];
+
+ cdRotatePointY(canvas, xmin, ymin, x, y, &rectY[0], sin_theta, cos_theta);
+ cdRotatePointY(canvas, xmax, ymin, x, y, &rectY[1], sin_theta, cos_theta);
+ cdRotatePointY(canvas, xmax, ymax, x, y, &rectY[2], sin_theta, cos_theta);
+ cdRotatePointY(canvas, xmin, ymax, x, y, &rectY[3], sin_theta, cos_theta);
+
+ ymin = ymax = rectY[0];
+ if (rectY[1] < ymin) ymin = rectY[1];
+ if (rectY[2] < ymin) ymin = rectY[2];
+ if (rectY[3] < ymin) ymin = rectY[3];
+ if (rectY[1] > ymax) ymax = rectY[1];
+ if (rectY[2] > ymax) ymax = rectY[2];
+ if (rectY[3] > ymax) ymax = rectY[3];
+ }
+
+ *hbox = ymax-ymin+1;
+}
+
+static void sSetTextTransform(cdCtxCanvas* ctxcanvas, double *x, double *y, int w, int h)
+{
+ int hbox;
+ cairo_matrix_t mtx;
+
+ sGetTransformTextHeight(ctxcanvas->canvas, (int)*x, (int)*y, w, h, &hbox);
+
+ /* move to (x,y) and remove a vertical offset since text reference point is top-left */
+ mtx.xx = 1; mtx.yx = 0;
+ mtx.xy = 0; mtx.yy = 1;
+ mtx.x0 = *x; mtx.y0 = *y - (hbox-1);
+ cairo_transform(ctxcanvas->cr, &mtx);
+
+ /* invert the text vertical orientation, relative to itself */
+ mtx.xx = 1; mtx.yx = 0;
+ mtx.xy = 0; mtx.yy = -1;
+ mtx.x0 = 0; mtx.y0 = hbox-1;
+ cairo_transform(ctxcanvas->cr, &mtx);
+
+ *x = 0;
+ *y = 0;
+}
+
static void cdftext(cdCtxCanvas *ctxcanvas, double x, double y, const char *s, int len)
{
PangoFontMetrics* metrics;
- int w, h, desc, dir = -1;
+ int w, h, desc, dir = -1, reset_transform = 0;
pango_layout_set_text(ctxcanvas->fontlayout, sStrConvertToUTF8(ctxcanvas, s, len), -1);
@@ -774,14 +862,25 @@ static void cdftext(cdCtxCanvas *ctxcanvas, double x, double y, const char *s, i
metrics = pango_context_get_metrics(ctxcanvas->fontcontext, ctxcanvas->fontdesc, pango_context_get_language(ctxcanvas->fontcontext));
desc = (((pango_font_metrics_get_descent(metrics)) + PANGO_SCALE/2) / PANGO_SCALE);
- if (ctxcanvas->canvas->text_orientation)
+ if (ctxcanvas->canvas->text_orientation ||
+ ctxcanvas->canvas->use_matrix ||
+ ctxcanvas->rotate_angle)
+ reset_transform = 1;
+
+ if (reset_transform)
{
cairo_save (ctxcanvas->cr);
+ cairo_identity_matrix(ctxcanvas->cr);
+ }
+
+ if (ctxcanvas->canvas->text_orientation)
+ {
cairo_translate(ctxcanvas->cr, x, y);
cairo_rotate(ctxcanvas->cr, -ctxcanvas->canvas->text_orientation*CD_DEG2RAD);
cairo_translate(ctxcanvas->cr, -x, -y);
}
+ /* move to top-left corner of the text */
switch (ctxcanvas->canvas->text_alignment)
{
case CD_BASE_RIGHT:
@@ -831,6 +930,15 @@ static void cdftext(cdCtxCanvas *ctxcanvas, double x, double y, const char *s, i
break;
}
+ if (ctxcanvas->canvas->use_matrix)
+ {
+ double* matrix = ctxcanvas->canvas->matrix;
+ sSetTransform(ctxcanvas, matrix);
+ sSetTextTransform(ctxcanvas, &x, &y, w, h);
+ }
+ else
+ sSetTransform(ctxcanvas, NULL);
+
/* Inform Pango to re-layout the text with the new transformation */
pango_cairo_update_layout(ctxcanvas->cr, ctxcanvas->fontlayout);
@@ -839,7 +947,7 @@ static void cdftext(cdCtxCanvas *ctxcanvas, double x, double y, const char *s, i
cairo_move_to(ctxcanvas->cr, x, y);
pango_cairo_show_layout(ctxcanvas->cr, ctxcanvas->fontlayout);
- if (ctxcanvas->canvas->text_orientation)
+ if (reset_transform)
cairo_restore(ctxcanvas->cr);
pango_font_metrics_unref(metrics);
@@ -1547,29 +1655,9 @@ static void cdtransform(cdCtxCanvas *ctxcanvas, const double* matrix)
ctxcanvas->canvas->invert_yaxis = 1;
if (matrix)
- {
- cairo_matrix_t mtx;
-
- /* configure a bottom-up coordinate system */
- mtx.xx = 1; mtx.yx = 0;
- mtx.xy = 0; mtx.yy = -1;
- mtx.x0 = 0; mtx.y0 = (ctxcanvas->canvas->h-1);
- cairo_transform(ctxcanvas->cr, &mtx);
ctxcanvas->canvas->invert_yaxis = 0;
- mtx.xx = matrix[0]; mtx.yx = matrix[1];
- mtx.xy = matrix[2]; mtx.yy = matrix[3];
- mtx.x0 = matrix[4]; mtx.y0 = matrix[5];
- cairo_transform(ctxcanvas->cr, &mtx);
- }
- else if (ctxcanvas->rotate_angle)
- {
- /* rotation = translate to point + rotation + translate back */
- /* the rotation must be corrected because of the Y axis orientation */
- cairo_translate(ctxcanvas->cr, ctxcanvas->rotate_center_x, _cdInvertYAxis(ctxcanvas->canvas, ctxcanvas->rotate_center_y));
- cairo_rotate(ctxcanvas->cr, (double)-ctxcanvas->rotate_angle * CD_DEG2RAD);
- cairo_translate(ctxcanvas->cr, -ctxcanvas->rotate_center_x, -_cdInvertYAxis(ctxcanvas->canvas, ctxcanvas->rotate_center_y));
- }
+ sSetTransform(ctxcanvas, matrix);
}
/******************************************************************/
diff --git a/src/gdiplus/cdwinp.cpp b/src/gdiplus/cdwinp.cpp
index 52c19a1..6827f53 100644
--- a/src/gdiplus/cdwinp.cpp
+++ b/src/gdiplus/cdwinp.cpp
@@ -65,13 +65,14 @@ void cdwpKillCanvas(cdCtxCanvas* ctxcanvas)
/* ctxcanvas eŽ liberado em cada driver */
}
-static int cdwpSetTransform(cdCtxCanvas* ctxcanvas, Matrix &transformMatrix, const double* matrix)
+static int sAddTransform(cdCtxCanvas* ctxcanvas, Matrix &transformMatrix, const double* matrix)
{
if (matrix)
{
// configure a bottom-up coordinate system
Matrix Matrix1((REAL)1, (REAL)0, (REAL)0, (REAL)-1, (REAL)0, (REAL)(ctxcanvas->canvas->h-1));
transformMatrix.Multiply(&Matrix1);
+
// add the global transform
Matrix Matrix2((REAL)matrix[0], (REAL)matrix[1], (REAL)matrix[2], (REAL)matrix[3], (REAL)matrix[4], (REAL)matrix[5]);
transformMatrix.Multiply(&Matrix2);
@@ -89,11 +90,11 @@ static int cdwpSetTransform(cdCtxCanvas* ctxcanvas, Matrix &transformMatrix, con
return 0;
}
-static void cdwpUpdateTransform(cdCtxCanvas* ctxcanvas)
+static void sUpdateTransform(cdCtxCanvas* ctxcanvas)
{
Matrix transformMatrix;
ctxcanvas->graphics->ResetTransform(); // reset to the identity.
- if (cdwpSetTransform(ctxcanvas, transformMatrix, ctxcanvas->canvas->use_matrix? ctxcanvas->canvas->matrix: NULL))
+ if (sAddTransform(ctxcanvas, transformMatrix, ctxcanvas->canvas->use_matrix? ctxcanvas->canvas->matrix: NULL))
ctxcanvas->graphics->SetTransform(&transformMatrix);
}
@@ -1304,7 +1305,7 @@ static void sTextBox(cdCtxCanvas* ctxcanvas, WCHAR *ws, int len, int x, int y, i
*ymin += ydir * (*h);
}
-static void cdwpCanvasGetTextHeight(cdCanvas* canvas, int x, int y, int w, int h, int *hbox)
+static void sGetTransformTextHeight(cdCanvas* canvas, int x, int y, int w, int h, int *hbox)
{
int xmin, xmax, ymin, ymax;
@@ -1340,21 +1341,12 @@ static void cdwpCanvasGetTextHeight(cdCanvas* canvas, int x, int y, int w, int h
*hbox = ymax-ymin+1;
}
-static void cdwpTextTransform(cdCtxCanvas* ctxcanvas, int *x, int *y, int w, int h, Matrix &transformMatrix)
+static void sAddTextTransform(cdCtxCanvas* ctxcanvas, int *x, int *y, int w, int h, Matrix &transformMatrix)
{
int hbox;
- double* matrix = ctxcanvas->canvas->matrix;
Matrix m1;
- cdwpCanvasGetTextHeight(ctxcanvas->canvas, *x, *y, w, h, &hbox);
-
- // configure a bottom-up coordinate system
- m1.SetElements((REAL)1, (REAL)0, (REAL)0, (REAL)-1, (REAL)0, (REAL)(ctxcanvas->canvas->h-1));
- transformMatrix.Multiply(&m1);
-
- // add the global transform
- m1.SetElements((REAL)matrix[0], (REAL)matrix[1], (REAL)matrix[2], (REAL)matrix[3], (REAL)matrix[4], (REAL)matrix[5]);
- transformMatrix.Multiply(&m1);
+ sGetTransformTextHeight(ctxcanvas->canvas, *x, *y, w, h, &hbox);
// move to (x,y) and remove a vertical offset since text reference point is top-left
m1.SetElements((REAL)1, (REAL)0, (REAL)0, (REAL)1, (REAL)*x, (REAL)(*y - (hbox-1)));
@@ -1387,10 +1379,12 @@ static void cdtext(cdCtxCanvas* ctxcanvas, int x, int y, const char *s, int len)
if (ctxcanvas->canvas->use_matrix)
{
- cdwpTextTransform(ctxcanvas, &x, &y, w, h, transformMatrix);
+ double* matrix = ctxcanvas->canvas->matrix;
+ sAddTransform(ctxcanvas, transformMatrix, matrix);
+ sAddTextTransform(ctxcanvas, &x, &y, w, h, transformMatrix);
use_transform = 1;
}
- else if (cdwpSetTransform(ctxcanvas, transformMatrix, NULL))
+ else if (sAddTransform(ctxcanvas, transformMatrix, NULL))
use_transform = 1;
if (ctxcanvas->canvas->new_region)
@@ -1419,7 +1413,7 @@ static void cdtext(cdCtxCanvas* ctxcanvas, int x, int y, const char *s, int len)
ctxcanvas->lineBrush);
if (use_transform)
- cdwpUpdateTransform(ctxcanvas); // reset transform
+ sUpdateTransform(ctxcanvas); // reset transform
ctxcanvas->dirty = 1;
}
@@ -1616,7 +1610,7 @@ static void cdtransform(cdCtxCanvas *ctxcanvas, const double* matrix)
else
ctxcanvas->canvas->invert_yaxis = 1;
- if (cdwpSetTransform(ctxcanvas, transformMatrix, matrix))
+ if (sAddTransform(ctxcanvas, transformMatrix, matrix))
ctxcanvas->graphics->SetTransform(&transformMatrix);
}
@@ -2691,7 +2685,7 @@ void cdwpUpdateCanvas(cdCtxCanvas* ctxcanvas)
else
set_aa_attrib(ctxcanvas, NULL);
- cdwpUpdateTransform(ctxcanvas);
+ sUpdateTransform(ctxcanvas);
}
/*