| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (c) 2008, Google Inc. All rights reserved. | 2 * Copyright (c) 2008, Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
| 6 * met: | 6 * met: |
| 7 * | 7 * |
| 8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
| (...skipping 29 matching lines...) Expand all Loading... |
| 40 #include "SkCanvas.h" | 40 #include "SkCanvas.h" |
| 41 #include "SkDevice.h" | 41 #include "SkDevice.h" |
| 42 #include "SkPaint.h" | 42 #include "SkPaint.h" |
| 43 #include "SkShader.h" | 43 #include "SkShader.h" |
| 44 #include "SkTemplates.h" | 44 #include "SkTemplates.h" |
| 45 | 45 |
| 46 namespace WebCore { | 46 namespace WebCore { |
| 47 | 47 |
| 48 static void skiaDrawText(PlatformContextSkia* context, | 48 static void skiaDrawText(PlatformContextSkia* context, |
| 49 const SkPoint& point, | 49 const SkPoint& point, |
| 50 const SkRect& textRect, |
| 50 SkPaint* paint, | 51 SkPaint* paint, |
| 51 const WORD* glyphs, | 52 const WORD* glyphs, |
| 52 const int* advances, | 53 const int* advances, |
| 53 const GOFFSET* offsets, | 54 const GOFFSET* offsets, |
| 54 int numGlyphs) | 55 int numGlyphs) |
| 55 { | 56 { |
| 56 // Reserve space for 64 SkPoints on the stack. If numGlyphs is larger, the a
rray | 57 // Reserve space for 64 SkPoints on the stack. If numGlyphs is larger, the a
rray |
| 57 // will dynamically allocate it space for numGlyph glyphs. This is used to s
tore | 58 // will dynamically allocate it space for numGlyph glyphs. This is used to s
tore |
| 58 // the computed x,y locations. In the case where offsets==null, then we use
it | 59 // the computed x,y locations. In the case where offsets==null, then we use
it |
| 59 // to store (twice as many) SkScalars for x[] | 60 // to store (twice as many) SkScalars for x[] |
| 60 static const size_t kLocalGlyphMax = 64; | 61 static const size_t kLocalGlyphMax = 64; |
| 61 | 62 |
| 62 SkScalar x = point.fX; | 63 SkScalar x = point.fX; |
| 63 SkScalar y = point.fY; | 64 SkScalar y = point.fY; |
| 64 if (offsets) { | 65 if (offsets) { |
| 65 SkAutoSTArray<kLocalGlyphMax, SkPoint> storage(numGlyphs); | 66 SkAutoSTArray<kLocalGlyphMax, SkPoint> storage(numGlyphs); |
| 66 SkPoint* pos = storage.get(); | 67 SkPoint* pos = storage.get(); |
| 67 for (int i = 0; i < numGlyphs; i++) { | 68 for (int i = 0; i < numGlyphs; i++) { |
| 68 // GDI has dv go up, so we negate it | 69 // GDI has dv go up, so we negate it |
| 69 pos[i].set(x + SkIntToScalar(offsets[i].du), | 70 pos[i].set(x + SkIntToScalar(offsets[i].du), |
| 70 y + -SkIntToScalar(offsets[i].dv)); | 71 y + -SkIntToScalar(offsets[i].dv)); |
| 71 x += SkIntToScalar(advances[i]); | 72 x += SkIntToScalar(advances[i]); |
| 72 } | 73 } |
| 73 context->drawPosText(glyphs, numGlyphs * sizeof(uint16_t), pos, *paint); | 74 context->drawPosText(glyphs, numGlyphs * sizeof(uint16_t), pos, textRect
, *paint); |
| 74 } else { | 75 } else { |
| 75 SkAutoSTArray<kLocalGlyphMax * 2, SkScalar> storage(numGlyphs); | 76 SkAutoSTArray<kLocalGlyphMax * 2, SkScalar> storage(numGlyphs); |
| 76 SkScalar* xpos = storage.get(); | 77 SkScalar* xpos = storage.get(); |
| 77 for (int i = 0; i < numGlyphs; i++) { | 78 for (int i = 0; i < numGlyphs; i++) { |
| 78 xpos[i] = x; | 79 xpos[i] = x; |
| 79 x += SkIntToScalar(advances[i]); | 80 x += SkIntToScalar(advances[i]); |
| 80 } | 81 } |
| 81 context->drawPosTextH(glyphs, numGlyphs * sizeof(uint16_t), | 82 context->drawPosTextH(glyphs, numGlyphs * sizeof(uint16_t), |
| 82 xpos, y, *paint); | 83 xpos, y, textRect, *paint); |
| 83 } | 84 } |
| 84 } | 85 } |
| 85 | 86 |
| 86 // Lookup the current system settings for font smoothing. | 87 // Lookup the current system settings for font smoothing. |
| 87 // We cache these values for performance, but if the browser has away to be | 88 // We cache these values for performance, but if the browser has away to be |
| 88 // notified when these change, we could re-query them at that time. | 89 // notified when these change, we could re-query them at that time. |
| 89 static uint32_t getDefaultGDITextFlags() | 90 static uint32_t getDefaultGDITextFlags() |
| 90 { | 91 { |
| 91 static bool gInited; | 92 static bool gInited; |
| 92 static uint32_t gFlags; | 93 static uint32_t gFlags; |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 154 flags |= textFlags; | 155 flags |= textFlags; |
| 155 paint->setFlags(flags); | 156 paint->setFlags(flags); |
| 156 } | 157 } |
| 157 | 158 |
| 158 static void paintSkiaText(GraphicsContext* context, HFONT hfont, | 159 static void paintSkiaText(GraphicsContext* context, HFONT hfont, |
| 159 SkTypeface* face, float size, int quality, | 160 SkTypeface* face, float size, int quality, |
| 160 int numGlyphs, | 161 int numGlyphs, |
| 161 const WORD* glyphs, | 162 const WORD* glyphs, |
| 162 const int* advances, | 163 const int* advances, |
| 163 const GOFFSET* offsets, | 164 const GOFFSET* offsets, |
| 164 const SkPoint* origin) | 165 const SkPoint& origin, |
| 166 const SkRect& textRect) |
| 165 { | 167 { |
| 166 PlatformContextSkia* platformContext = context->platformContext(); | 168 PlatformContextSkia* platformContext = context->platformContext(); |
| 167 TextDrawingModeFlags textMode = platformContext->getTextDrawingMode(); | 169 TextDrawingModeFlags textMode = platformContext->getTextDrawingMode(); |
| 168 // Ensure font load for printing, because PDF device needs it. | 170 // Ensure font load for printing, because PDF device needs it. |
| 169 if (platformContext->isVector()) | 171 if (platformContext->isVector()) |
| 170 FontPlatformData::ensureFontLoaded(hfont); | 172 FontPlatformData::ensureFontLoaded(hfont); |
| 171 | 173 |
| 172 // Filling (if necessary). This is the common case. | 174 // Filling (if necessary). This is the common case. |
| 173 SkPaint paint; | 175 SkPaint paint; |
| 174 platformContext->setupPaintForFilling(&paint); | 176 platformContext->setupPaintForFilling(&paint); |
| 175 paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding); | 177 paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding); |
| 176 setupPaintForFont(&paint, platformContext, face, size, quality); | 178 setupPaintForFont(&paint, platformContext, face, size, quality); |
| 177 | 179 |
| 178 bool didFill = false; | 180 bool didFill = false; |
| 179 | 181 |
| 180 if ((textMode & TextModeFill) && (SkColorGetA(paint.getColor()) || paint.get
Looper())) { | 182 if ((textMode & TextModeFill) && (SkColorGetA(paint.getColor()) || paint.get
Looper())) { |
| 181 skiaDrawText(platformContext, *origin, &paint, &glyphs[0], &advances[0],
&offsets[0], numGlyphs); | 183 skiaDrawText(platformContext, origin, textRect, &paint, &glyphs[0], &adv
ances[0], &offsets[0], numGlyphs); |
| 182 didFill = true; | 184 didFill = true; |
| 183 } | 185 } |
| 184 | 186 |
| 185 // Stroking on top (if necessary). | 187 // Stroking on top (if necessary). |
| 186 if ((textMode & TextModeStroke) | 188 if ((textMode & TextModeStroke) |
| 187 && platformContext->getStrokeStyle() != NoStroke | 189 && platformContext->getStrokeStyle() != NoStroke |
| 188 && platformContext->getStrokeThickness() > 0) { | 190 && platformContext->getStrokeThickness() > 0) { |
| 189 | 191 |
| 190 paint.reset(); | 192 paint.reset(); |
| 191 platformContext->setupPaintForStroking(&paint, 0, 0); | 193 platformContext->setupPaintForStroking(&paint, 0, 0); |
| 192 paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding); | 194 paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding); |
| 193 setupPaintForFont(&paint, platformContext, face, size, quality); | 195 setupPaintForFont(&paint, platformContext, face, size, quality); |
| 194 | 196 |
| 195 if (didFill) { | 197 if (didFill) { |
| 196 // If there is a shadow and we filled above, there will already be | 198 // If there is a shadow and we filled above, there will already be |
| 197 // a shadow. We don't want to draw it again or it will be too dark | 199 // a shadow. We don't want to draw it again or it will be too dark |
| 198 // and it will go on top of the fill. | 200 // and it will go on top of the fill. |
| 199 // | 201 // |
| 200 // Note that this isn't strictly correct, since the stroke could be | 202 // Note that this isn't strictly correct, since the stroke could be |
| 201 // very thick and the shadow wouldn't account for this. The "right" | 203 // very thick and the shadow wouldn't account for this. The "right" |
| 202 // thing would be to draw to a new layer and then draw that layer | 204 // thing would be to draw to a new layer and then draw that layer |
| 203 // with a shadow. But this is a lot of extra work for something | 205 // with a shadow. But this is a lot of extra work for something |
| 204 // that isn't normally an issue. | 206 // that isn't normally an issue. |
| 205 paint.setLooper(0); | 207 paint.setLooper(0); |
| 206 } | 208 } |
| 207 | 209 |
| 208 skiaDrawText(platformContext, *origin, &paint, &glyphs[0], &advances[0],
&offsets[0], numGlyphs); | 210 skiaDrawText(platformContext, origin, textRect, &paint, &glyphs[0], &adv
ances[0], &offsets[0], numGlyphs); |
| 209 } | 211 } |
| 210 } | 212 } |
| 211 | 213 |
| 212 ////////////////////////////////////////////////////////////////////////////////
/////////// | 214 ////////////////////////////////////////////////////////////////////////////////
/////////// |
| 213 | 215 |
| 214 void paintSkiaText(GraphicsContext* context, | 216 void paintSkiaText(GraphicsContext* context, |
| 215 const FontPlatformData& data, | 217 const FontPlatformData& data, |
| 216 int numGlyphs, | 218 int numGlyphs, |
| 217 const WORD* glyphs, | 219 const WORD* glyphs, |
| 218 const int* advances, | 220 const int* advances, |
| 219 const GOFFSET* offsets, | 221 const GOFFSET* offsets, |
| 220 const SkPoint* origin) | 222 const SkPoint& origin, |
| 223 const SkRect& textRect) |
| 221 { | 224 { |
| 222 paintSkiaText(context, data.hfont(), data.typeface(), data.size(), data.lfQu
ality(), | 225 paintSkiaText(context, data.hfont(), data.typeface(), data.size(), data.lfQu
ality(), |
| 223 numGlyphs, glyphs, advances, offsets, origin); | 226 numGlyphs, glyphs, advances, offsets, origin, textRect); |
| 224 } | 227 } |
| 225 | 228 |
| 226 void paintSkiaText(GraphicsContext* context, | 229 void paintSkiaText(GraphicsContext* context, |
| 227 HFONT hfont, | 230 HFONT hfont, |
| 228 int numGlyphs, | 231 int numGlyphs, |
| 229 const WORD* glyphs, | 232 const WORD* glyphs, |
| 230 const int* advances, | 233 const int* advances, |
| 231 const GOFFSET* offsets, | 234 const GOFFSET* offsets, |
| 232 const SkPoint* origin) | 235 const SkPoint& origin, |
| 236 const SkRect& textRect) |
| 233 { | 237 { |
| 234 int size; | 238 int size; |
| 235 int quality; | 239 int quality; |
| 236 SkTypeface* face = CreateTypefaceFromHFont(hfont, &size, &quality); | 240 SkTypeface* face = CreateTypefaceFromHFont(hfont, &size, &quality); |
| 237 SkAutoUnref aur(face); | 241 SkAutoUnref aur(face); |
| 238 | 242 |
| 239 paintSkiaText(context, hfont, face, size, quality, numGlyphs, glyphs, advanc
es, offsets, origin); | 243 paintSkiaText(context, hfont, face, size, quality, numGlyphs, glyphs, advanc
es, offsets, origin, textRect); |
| 240 } | 244 } |
| 241 | 245 |
| 242 } // namespace WebCore | 246 } // namespace WebCore |
| OLD | NEW |