Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 /* | |
| 2 * Copyright 2014 Google Inc. | |
| 3 * | |
| 4 * Use of this source code is governed by a BSD-style license that can be | |
| 5 * found in the LICENSE file. | |
| 6 */ | |
| 7 | |
| 8 #include "SkTextBlob.h" | |
| 9 | |
| 10 #include "SkDevice.h" | |
| 11 | |
| 12 const SkTextChunk* SkTextChunk::Create(const uint16_t* glyphs, size_t count, con st SkPaint& paint, | |
| 13 const SkRect* bounds) { | |
| 14 if (NULL == glyphs || 0 == count) { | |
| 15 return NULL; | |
| 16 } | |
| 17 | |
| 18 return SkNEW_ARGS(SkTextChunk, (glyphs, count, paint, bounds)); | |
| 19 } | |
| 20 | |
| 21 const SkTextChunk* SkTextChunk::Create(const uint16_t* glyphs, size_t count, con st SkScalar* pos, | |
| 22 const SkPaint& paint, const SkRect* bounds) { | |
| 23 if (NULL == glyphs || NULL == pos || 0 == count) { | |
| 24 return NULL; | |
| 25 } | |
| 26 | |
| 27 return SkNEW_ARGS(SkTextChunk, (glyphs, count, pos, paint, bounds)); | |
| 28 } | |
| 29 | |
| 30 const SkTextChunk* SkTextChunk::Create(const uint16_t* glyphs, size_t count, con st SkPoint* pos, | |
| 31 const SkPaint& paint, const SkRect* bounds) { | |
| 32 if (NULL == glyphs || NULL == pos || 0 == count) { | |
| 33 return NULL; | |
| 34 } | |
| 35 | |
| 36 return SkNEW_ARGS(SkTextChunk, (glyphs, count, pos, paint, bounds)); | |
| 37 } | |
| 38 | |
| 39 SkTextChunk::SkTextChunk(const uint16_t *glyphs, size_t count, const SkPaint &pa int, | |
| 40 const SkRect* bounds) | |
| 41 : fPos(NULL) | |
| 42 , fFont(paint) | |
| 43 , fScalarsPerPos(0) { | |
| 44 | |
| 45 SkASSERT(SkPaint::kGlyphID_TextEncoding == paint.getTextEncoding()); | |
| 46 init(glyphs, count, bounds, NULL); | |
| 47 } | |
| 48 | |
| 49 SkTextChunk::SkTextChunk(const uint16_t *glyphs, size_t count, const SkScalar* p os, | |
| 50 const SkPaint &paint, const SkRect* bounds) | |
| 51 : fPos(NULL) | |
| 52 , fFont(paint) | |
| 53 , fScalarsPerPos(1) { | |
| 54 | |
| 55 SkASSERT(SkPaint::kGlyphID_TextEncoding == paint.getTextEncoding()); | |
| 56 init(glyphs, count, bounds, pos); | |
| 57 } | |
| 58 | |
| 59 SkTextChunk::SkTextChunk(const uint16_t *glyphs, size_t count, const SkPoint* po s, | |
| 60 const SkPaint &paint, const SkRect* bounds) | |
| 61 : fPos(NULL) | |
| 62 , fFont(paint) | |
| 63 , fScalarsPerPos(2) { | |
| 64 | |
| 65 SK_COMPILE_ASSERT(sizeof(SkScalar) * 2 == sizeof(SkPoint), point_is_two_scal ars); | |
| 66 | |
| 67 SkASSERT(SkPaint::kGlyphID_TextEncoding == paint.getTextEncoding()); | |
| 68 init(glyphs, count, bounds, (const SkScalar*)pos); | |
|
mtklein
2014/08/14 14:00:42
Can't hurt to label this explicitly as reinterpret
f(malita)
2014/08/14 14:29:26
Done.
| |
| 69 } | |
| 70 | |
| 71 SkTextChunk::~SkTextChunk() { | |
| 72 sk_free(fGlyphs); | |
| 73 sk_free(fPos); | |
| 74 } | |
| 75 | |
| 76 void SkTextChunk::init(const uint16_t* glyphs, size_t count, const SkRect* bound s, | |
| 77 const SkScalar* pos) { | |
| 78 SkASSERT(glyphs); | |
| 79 SkASSERT(count > 0); | |
| 80 | |
| 81 size_t storageSize = sizeof(uint16_t) * count; | |
| 82 | |
| 83 fGlyphCount = count; | |
| 84 fGlyphs = static_cast<uint16_t*>(sk_malloc_throw(storageSize)); | |
| 85 memcpy(fGlyphs, glyphs, storageSize); | |
| 86 | |
| 87 fBoundsDirty = NULL == bounds; | |
| 88 if (!fBoundsDirty) { | |
| 89 fBounds = *bounds; | |
| 90 } | |
| 91 | |
| 92 if (NULL != pos) { | |
| 93 size_t posStorageSize = sizeof(SkScalar) * fScalarsPerPos * count; | |
| 94 fPos = static_cast<SkScalar*>(sk_malloc_throw(posStorageSize)); | |
| 95 memcpy(fPos, pos, posStorageSize); | |
| 96 } | |
| 97 } | |
| 98 | |
| 99 const SkRect& SkTextChunk::bounds() const { | |
| 100 if (fBoundsDirty) { | |
| 101 fFont.measureText(fGlyphs, fGlyphCount, &fBounds); | |
| 102 fBoundsDirty = false; | |
| 103 } | |
| 104 | |
| 105 return fBounds; | |
| 106 } | |
| 107 | |
| 108 void SkTextChunk::draw(SkBaseDevice* device, const SkDraw& draw, const SkPaint& paint) const { | |
| 109 SkASSERT(NULL != device); | |
| 110 SkASSERT(SkPaint::kGlyphID_TextEncoding == paint.getTextEncoding()); | |
| 111 | |
| 112 size_t length = sizeof(uint16_t) * fGlyphCount; | |
| 113 if (NULL != fPos) { | |
| 114 SkASSERT(1 == fScalarsPerPos || 2 == fScalarsPerPos); | |
| 115 device->drawPosText(draw, fGlyphs, length, fPos, 0, fScalarsPerPos, pain t); | |
| 116 } else { | |
| 117 SkASSERT(0 == fScalarsPerPos); | |
| 118 device->drawText(draw, fGlyphs, length, 0, 0, paint); | |
| 119 } | |
| 120 } | |
| 121 | |
| 122 const SkTextBlob* SkTextBlob::Create(const SkTextChunk *chunk) { | |
| 123 SkTDArray<const SkTextChunk*> chunks; | |
| 124 chunks.setReserve(1); | |
| 125 *chunks.append() = chunk; | |
| 126 return SkNEW_ARGS(SkTextBlob, (chunks)); | |
| 127 } | |
| 128 | |
| 129 const SkTextBlob* SkTextBlob::Create(const SkTDArray<const SkTextChunk*>& chunks ) { | |
| 130 return SkNEW_ARGS(SkTextBlob, (chunks)); | |
| 131 } | |
| 132 | |
| 133 SkTextBlob::SkTextBlob(const SkTDArray<const SkTextChunk*>& chunks) | |
| 134 : fChunks(chunks) | |
| 135 , fUniqueID(SK_InvalidGenID) { | |
| 136 } | |
| 137 | |
| 138 SkTextBlob::~SkTextBlob() { | |
| 139 Iter it(this); | |
| 140 while (const SkTextChunk* chunk = it.next()) { | |
| 141 SkDELETE(chunk); | |
| 142 } | |
| 143 } | |
| 144 | |
| 145 uint32_t SkTextBlob::uniqueID() const { | |
| 146 static int32_t gTextBlobGenerationID; // = 0; | |
| 147 | |
| 148 // do a loop in case our global wraps around, as we never want to | |
| 149 // return SK_InvalidGenID | |
| 150 while (SK_InvalidGenID == fUniqueID) { | |
| 151 fUniqueID = sk_atomic_inc(&gTextBlobGenerationID) + 1; | |
| 152 } | |
| 153 | |
| 154 return fUniqueID; | |
| 155 } | |
| 156 | |
| 157 SkTextBlobBuilder::SkTextBlobBuilder() { | |
| 158 } | |
| 159 | |
| 160 SkTextBlobBuilder::~SkTextBlobBuilder() { | |
| 161 // unused chunks. | |
| 162 for (int i = 0; i < fChunks.count(); ++i) { | |
| 163 SkDELETE(fChunks[i]); | |
| 164 } | |
| 165 } | |
| 166 | |
| 167 const SkTextBlob* SkTextBlobBuilder::build() { | |
| 168 const SkTextBlob* blob = SkTextBlob::Create(fChunks); | |
| 169 fChunks.rewind(); | |
| 170 return blob; | |
| 171 } | |
| 172 | |
| 173 void SkTextBlobBuilder::addChunk(const SkTextChunk* chunk) { | |
| 174 *fChunks.append() = chunk; | |
| 175 } | |
| 176 | |
| 177 | |
| OLD | NEW |