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 |