| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2011 Google Inc. | 2 * Copyright 2011 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #include "SkTypes.h" | 8 #include "SkTypes.h" |
| 9 #undef GetGlyphIndices | 9 #undef GetGlyphIndices |
| 10 | 10 |
| (...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 203 // there are any embedded bi-level bitmaps of that size. If there are, then | 203 // there are any embedded bi-level bitmaps of that size. If there are, then |
| 204 // force bitmaps by requesting bi-level rendering. | 204 // force bitmaps by requesting bi-level rendering. |
| 205 // | 205 // |
| 206 // FreeType allows for separate ppemX and ppemY, but DirectWrite assumes | 206 // FreeType allows for separate ppemX and ppemY, but DirectWrite assumes |
| 207 // square pixels and only uses ppemY. Therefore the transform must track any | 207 // square pixels and only uses ppemY. Therefore the transform must track any |
| 208 // non-uniform x-scale. | 208 // non-uniform x-scale. |
| 209 // | 209 // |
| 210 // Also, rotated glyphs should have the same absolute advance widths as | 210 // Also, rotated glyphs should have the same absolute advance widths as |
| 211 // horizontal glyphs and the subpixel flag should not affect glyph shapes. | 211 // horizontal glyphs and the subpixel flag should not affect glyph shapes. |
| 212 | 212 |
| 213 // A is the total matrix. | 213 SkVector scale; |
| 214 SkMatrix A; | 214 SkMatrix GsA; |
| 215 fRec.getSingleMatrix(&A); | 215 fRec.computeMatrices(SkScalerContextRec::kVertical_PreMatrixScale, |
| 216 &scale, &fSkXform, &GsA, &fG_inv); |
| 216 | 217 |
| 217 // h is where A maps the horizontal baseline. | 218 fXform.m11 = SkScalarToFloat(fSkXform.getScaleX()); |
| 218 SkPoint h = SkPoint::Make(SK_Scalar1, 0); | 219 fXform.m12 = SkScalarToFloat(fSkXform.getSkewY()); |
| 219 A.mapPoints(&h, 1); | 220 fXform.m21 = SkScalarToFloat(fSkXform.getSkewX()); |
| 221 fXform.m22 = SkScalarToFloat(fSkXform.getScaleY()); |
| 222 fXform.dx = 0; |
| 223 fXform.dy = 0; |
| 220 | 224 |
| 221 // G is the Givens Matrix for A (rotational matrix where GA[0][1] == 0). | 225 fGsA.m11 = SkScalarToFloat(GsA.get(SkMatrix::kMScaleX)); |
| 222 SkMatrix G; | 226 fGsA.m12 = SkScalarToFloat(GsA.get(SkMatrix::kMSkewY)); // This should be ~0
. |
| 223 SkComputeGivensRotation(h, &G); | 227 fGsA.m21 = SkScalarToFloat(GsA.get(SkMatrix::kMSkewX)); |
| 224 | 228 fGsA.m22 = SkScalarToFloat(GsA.get(SkMatrix::kMScaleY)); |
| 225 // GA is the matrix A with rotation removed. | 229 fGsA.dx = 0; |
| 226 SkMatrix GA(G); | 230 fGsA.dy = 0; |
| 227 GA.preConcat(A); | |
| 228 | 231 |
| 229 // realTextSize is the actual device size we want (as opposed to the size th
e user requested). | 232 // realTextSize is the actual device size we want (as opposed to the size th
e user requested). |
| 230 // gdiTextSize is the size we request when GDI compatible. | 233 // gdiTextSize is the size we request when GDI compatible. |
| 231 // If the scale is negative, this means the matrix will do the flip anyway. | 234 // If the scale is negative, this means the matrix will do the flip anyway. |
| 232 SkScalar realTextSize = SkScalarAbs(GA.get(SkMatrix::kMScaleY)); | 235 const SkScalar realTextSize = scale.fY; |
| 233 // Due to floating point math, the lower bits are suspect. Round carefully. | 236 // Due to floating point math, the lower bits are suspect. Round carefully. |
| 234 SkScalar gdiTextSize = SkScalarRoundToScalar(realTextSize * 64.0f) / 64.0f; | 237 SkScalar gdiTextSize = SkScalarRoundToScalar(realTextSize * 64.0f) / 64.0f; |
| 235 if (gdiTextSize == 0) { | 238 if (gdiTextSize == 0) { |
| 236 gdiTextSize = SK_Scalar1; | 239 gdiTextSize = SK_Scalar1; |
| 237 } | 240 } |
| 238 | 241 |
| 239 bool bitmapRequested = SkToBool(fRec.fFlags & SkScalerContext::kEmbeddedBitm
apText_Flag); | 242 bool bitmapRequested = SkToBool(fRec.fFlags & SkScalerContext::kEmbeddedBitm
apText_Flag); |
| 240 bool treatLikeBitmap = false; | 243 bool treatLikeBitmap = false; |
| 241 bool axisAlignedBitmap = false; | 244 bool axisAlignedBitmap = false; |
| 242 if (bitmapRequested) { | 245 if (bitmapRequested) { |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 293 fRenderingMode = DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC; | 296 fRenderingMode = DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC; |
| 294 fTextureType = DWRITE_TEXTURE_CLEARTYPE_3x1; | 297 fTextureType = DWRITE_TEXTURE_CLEARTYPE_3x1; |
| 295 fTextSizeMeasure = realTextSize; | 298 fTextSizeMeasure = realTextSize; |
| 296 fMeasuringMode = DWRITE_MEASURING_MODE_NATURAL; | 299 fMeasuringMode = DWRITE_MEASURING_MODE_NATURAL; |
| 297 } | 300 } |
| 298 | 301 |
| 299 if (this->isSubpixel()) { | 302 if (this->isSubpixel()) { |
| 300 fTextSizeMeasure = realTextSize; | 303 fTextSizeMeasure = realTextSize; |
| 301 fMeasuringMode = DWRITE_MEASURING_MODE_NATURAL; | 304 fMeasuringMode = DWRITE_MEASURING_MODE_NATURAL; |
| 302 } | 305 } |
| 303 | |
| 304 // Remove the realTextSize, as that is the text height scale currently in A. | |
| 305 SkScalar scale = SkScalarInvert(realTextSize); | |
| 306 | |
| 307 // fSkXform is the total matrix A without the text height scale. | |
| 308 fSkXform = A; | |
| 309 fSkXform.preScale(scale, scale); //remove the text height scale. | |
| 310 | |
| 311 fXform.m11 = SkScalarToFloat(fSkXform.getScaleX()); | |
| 312 fXform.m12 = SkScalarToFloat(fSkXform.getSkewY()); | |
| 313 fXform.m21 = SkScalarToFloat(fSkXform.getSkewX()); | |
| 314 fXform.m22 = SkScalarToFloat(fSkXform.getScaleY()); | |
| 315 fXform.dx = 0; | |
| 316 fXform.dy = 0; | |
| 317 | |
| 318 // GsA is the non-rotational part of A without the text height scale. | |
| 319 SkMatrix GsA(GA); | |
| 320 GsA.preScale(scale, scale); //remove text height scale, G is rotational so r
eorders with scale. | |
| 321 | |
| 322 fGsA.m11 = SkScalarToFloat(GsA.get(SkMatrix::kMScaleX)); | |
| 323 fGsA.m12 = SkScalarToFloat(GsA.get(SkMatrix::kMSkewY)); // This should be ~0
. | |
| 324 fGsA.m21 = SkScalarToFloat(GsA.get(SkMatrix::kMSkewX)); | |
| 325 fGsA.m22 = SkScalarToFloat(GsA.get(SkMatrix::kMScaleY)); | |
| 326 fGsA.dx = 0; | |
| 327 fGsA.dy = 0; | |
| 328 | |
| 329 // fG_inv is G inverse, which is fairly simple since G is 2x2 rotational. | |
| 330 fG_inv.setAll(G.get(SkMatrix::kMScaleX), -G.get(SkMatrix::kMSkewX), G.get(Sk
Matrix::kMTransX), | |
| 331 -G.get(SkMatrix::kMSkewY), G.get(SkMatrix::kMScaleY), G.get(Sk
Matrix::kMTransY), | |
| 332 G.get(SkMatrix::kMPersp0), G.get(SkMatrix::kMPersp1), G.get(Sk
Matrix::kMPersp2)); | |
| 333 } | 306 } |
| 334 | 307 |
| 335 SkScalerContext_DW::~SkScalerContext_DW() { | 308 SkScalerContext_DW::~SkScalerContext_DW() { |
| 336 } | 309 } |
| 337 | 310 |
| 338 unsigned SkScalerContext_DW::generateGlyphCount() { | 311 unsigned SkScalerContext_DW::generateGlyphCount() { |
| 339 if (fGlyphCount < 0) { | 312 if (fGlyphCount < 0) { |
| 340 fGlyphCount = fTypeface->fDWriteFontFace->GetGlyphCount(); | 313 fGlyphCount = fTypeface->fDWriteFontFace->GetGlyphCount(); |
| 341 } | 314 } |
| 342 return fGlyphCount; | 315 return fGlyphCount; |
| (...skipping 406 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 749 NULL, //advances | 722 NULL, //advances |
| 750 NULL, //offsets | 723 NULL, //offsets |
| 751 1, //num glyphs | 724 1, //num glyphs |
| 752 FALSE, //sideways | 725 FALSE, //sideways |
| 753 FALSE, //rtl | 726 FALSE, //rtl |
| 754 geometryToPath.get()), | 727 geometryToPath.get()), |
| 755 "Could not create glyph outline."); | 728 "Could not create glyph outline."); |
| 756 | 729 |
| 757 path->transform(fSkXform); | 730 path->transform(fSkXform); |
| 758 } | 731 } |
| OLD | NEW |