FT_Face ServerFont::GetTransformedFace(bool rotate, bool shear) const { fStyle->Lock(); FT_Face face = fStyle->FreeTypeFace(); if (!face) { fStyle->Unlock(); return NULL; } FT_Set_Char_Size(face, 0, int32(fSize * 64), 72, 72); if ((rotate && fRotation != 0) || (shear && fShear != 90)) { FT_Matrix rmatrix, smatrix; Angle rotationAngle(fRotation); rmatrix.xx = (FT_Fixed)( rotationAngle.Cosine() * 0x10000); rmatrix.xy = (FT_Fixed)(-rotationAngle.Sine() * 0x10000); rmatrix.yx = (FT_Fixed)( rotationAngle.Sine() * 0x10000); rmatrix.yy = (FT_Fixed)( rotationAngle.Cosine() * 0x10000); Angle shearAngle(fShear); smatrix.xx = (FT_Fixed)(0x10000); smatrix.xy = (FT_Fixed)(-shearAngle.Cosine() * 0x10000); smatrix.yx = (FT_Fixed)(0); smatrix.yy = (FT_Fixed)(0x10000); // Multiply togheter and apply transform FT_Matrix_Multiply(&rmatrix, &smatrix); FT_Set_Transform(face, &smatrix, NULL); } // fStyle will be unlocked in PutTransformedFace() return face; }
static void fill_context(TextContext *context, const FreeTypeInstance *ft, const PgFontObject *fontobj, const FontRenderMode *mode, const FT_Face font) { context->lib = ft->library; context->id = (FTC_FaceID)&(fontobj->id); context->font = font; context->charmap = ft->cache_charmap; context->do_transform = 0; if (mode->style & FT_STYLE_OBLIQUE) { context->transform = slant_matrix; context->do_transform = 1; } else { context->transform = unit_matrix; } if (mode->render_flags & FT_RFLAG_TRANSFORM) { FT_Matrix_Multiply(&mode->transform, &context->transform); context->do_transform = 1; } if (mode->rotation_angle != 0) { FT_Vector unit; FT_Matrix rotate; FT_Vector_Unit(&unit, mode->rotation_angle); rotate.xx = unit.x; /* cos(angle) */ rotate.xy = -unit.y; /* -sin(angle) */ rotate.yx = unit.y; /* sin(angle) */ rotate.yy = unit.x; /* cos(angle) */ FT_Matrix_Multiply(&rotate, &context->transform); context->do_transform = 1; } }
void simGetPenPos(cdCanvas* canvas, int x, int y, const char* s, int len, FT_Matrix *matrix, FT_Vector *pen) { int ox = x, oy = y; int old_invert_yaxis = canvas->invert_yaxis; int w, h, ascent, height, baseline; cdSimGetTextSizeFT(canvas->ctxcanvas, s, len, &w, &h); cdSimGetFontDimFT(canvas->ctxcanvas, NULL, &height, &ascent, NULL); baseline = height - ascent; /* in this case we are always upwards */ /* move to bottom left */ canvas->invert_yaxis = 0; cdTextTranslatePoint(canvas, x, y, w, h, baseline, &x, &y); canvas->invert_yaxis = old_invert_yaxis; /* move to the base line */ y += baseline; /* set up matrix */ matrix->xx = (FT_Fixed)0x10000L; matrix->xy = (FT_Fixed)0; matrix->yx = (FT_Fixed)0; matrix->yy = (FT_Fixed)0x10000L; if (canvas->text_orientation) { FT_Matrix text_matrix; double cos_theta = cos(canvas->text_orientation*CD_DEG2RAD); double sin_theta = sin(canvas->text_orientation*CD_DEG2RAD); /* manually rotate the initial point */ canvas->invert_yaxis = 0; cdRotatePoint(canvas, x, y, ox, oy, &x, &y, sin_theta, cos_theta); canvas->invert_yaxis = old_invert_yaxis; text_matrix.xx = (FT_Fixed)( cos_theta*0x10000L); text_matrix.xy = (FT_Fixed)(-sin_theta*0x10000L); text_matrix.yx = (FT_Fixed)( sin_theta*0x10000L); text_matrix.yy = (FT_Fixed)( cos_theta*0x10000L); FT_Matrix_Multiply(&text_matrix, matrix); } if (canvas->use_matrix) { FT_Matrix trans_matrix; trans_matrix.xx = (FT_Fixed)(canvas->matrix[0]*0x10000L); trans_matrix.yx = (FT_Fixed)(canvas->matrix[1]*0x10000L); trans_matrix.xy = (FT_Fixed)(canvas->matrix[2]*0x10000L); trans_matrix.yy = (FT_Fixed)(canvas->matrix[3]*0x10000L); FT_Matrix_Multiply(&trans_matrix, matrix); /* manually transform the initial point */ cdMatrixTransformPoint(canvas->matrix, x, y, &x, &y); } /* the pen position in 26.6 scale */ pen->x = x * 64; pen->y = y * 64; }