| Line | Source Code | Coverage |
|---|
| 1 | | - |
| 2 | | - |
| 3 | | - |
| 4 | | - |
| 5 | | - |
| 6 | | - |
| 7 | | - |
| 8 | | - |
| 9 | static inline int qt_next_power_of_two(int v) | - |
| 10 | { | - |
| 11 | v--; | - |
| 12 | v |= v >> 1; | - |
| 13 | v |= v >> 2; | - |
| 14 | v |= v >> 4; | - |
| 15 | v |= v >> 8; | - |
| 16 | v |= v >> 16; | - |
| 17 | ++v; | - |
| 18 | return v; executed: return v;Execution Count:2 | 2 |
| 19 | } | - |
| 20 | | - |
| 21 | int QTextureGlyphCache::calculateSubPixelPositionCount(glyph_t glyph) const | - |
| 22 | { | - |
| 23 | | - |
| 24 | | - |
| 25 | | - |
| 26 | QList<QImage> images; | - |
| 27 | for (int i=0; i<12; ++i) { | 0 |
| 28 | QImage img = textureMapForGlyph(glyph, QFixed::fromReal(i / 12.0)); | - |
| 29 | | - |
| 30 | if (images.isEmpty()) { never evaluated: images.isEmpty() | 0 |
| 31 | QPainterPath path; | - |
| 32 | QFixedPoint point; | - |
| 33 | m_current_fontengine->addGlyphsToPath(&glyph, &point, 1, &path, QTextItem::RenderFlags()); | - |
| 34 | | - |
| 35 | | - |
| 36 | if (path.isEmpty()) never evaluated: path.isEmpty() | 0 |
| 37 | break; | 0 |
| 38 | | - |
| 39 | images.append(img); | - |
| 40 | } else { | 0 |
| 41 | bool found = false; | - |
| 42 | for (int j=0; j<images.size(); ++j) { never evaluated: j<images.size() | 0 |
| 43 | if (images.at(j) == img) { never evaluated: images.at(j) == img | 0 |
| 44 | found = true; | - |
| 45 | break; | 0 |
| 46 | } | - |
| 47 | } | 0 |
| 48 | if (!found) | 0 |
| 49 | images.append(img); never executed: images.append(img); | 0 |
| 50 | } | 0 |
| 51 | } | - |
| 52 | | - |
| 53 | return images.size(); never executed: return images.size(); | 0 |
| 54 | } | - |
| 55 | | - |
| 56 | bool QTextureGlyphCache::populate(QFontEngine *fontEngine, int numGlyphs, const glyph_t *glyphs, | - |
| 57 | const QFixedPoint *positions) | - |
| 58 | { | - |
| 59 | | - |
| 60 | | - |
| 61 | | - |
| 62 | | - |
| 63 | | - |
| 64 | m_current_fontengine = fontEngine; | - |
| 65 | const int margin = m_current_fontengine->glyphMargin(m_type); | - |
| 66 | const int paddingDoubled = glyphPadding() * 2; | - |
| 67 | | - |
| 68 | bool supportsSubPixelPositions = fontEngine->supportsSubPixelPositions(); | - |
| 69 | if (fontEngine->m_subPixelPositionCount == 0) { evaluated: fontEngine->m_subPixelPositionCount == 0| yes Evaluation Count:1 | yes Evaluation Count:7 |
| 1-7 |
| 70 | if (!supportsSubPixelPositions) { partially evaluated: !supportsSubPixelPositions| yes Evaluation Count:1 | no Evaluation Count:0 |
| 0-1 |
| 71 | fontEngine->m_subPixelPositionCount = 1; | - |
| 72 | } else { executed: }Execution Count:1 | 1 |
| 73 | int i = 0; | - |
| 74 | while (fontEngine->m_subPixelPositionCount == 0 && i < numGlyphs) never evaluated: fontEngine->m_subPixelPositionCount == 0 never evaluated: i < numGlyphs | 0 |
| 75 | fontEngine->m_subPixelPositionCount = calculateSubPixelPositionCount(glyphs[i++]); never executed: fontEngine->m_subPixelPositionCount = calculateSubPixelPositionCount(glyphs[i++]); | 0 |
| 76 | } | 0 |
| 77 | } | - |
| 78 | | - |
| 79 | QHash<GlyphAndSubPixelPosition, Coord> listItemCoordinates; | - |
| 80 | int rowHeight = 0; | - |
| 81 | | - |
| 82 | QFontEngine::GlyphFormat format; | - |
| 83 | switch (m_type) { | - |
| 84 | case Raster_A8: format = QFontEngine::Format_A8; break; executed: break;Execution Count:8 | 8 |
| 85 | case Raster_RGBMask: format = QFontEngine::Format_A32; break; | 0 |
| 86 | default: format = QFontEngine::Format_Mono; break; | 0 |
| 87 | } | - |
| 88 | | - |
| 89 | | - |
| 90 | for (int i=0; i < numGlyphs; ++i) { evaluated: i < numGlyphs| yes Evaluation Count:24 | yes Evaluation Count:8 |
| 8-24 |
| 91 | const glyph_t glyph = glyphs[i]; | - |
| 92 | | - |
| 93 | QFixed subPixelPosition; | - |
| 94 | if (supportsSubPixelPositions) { partially evaluated: supportsSubPixelPositions| no Evaluation Count:0 | yes Evaluation Count:24 |
| 0-24 |
| 95 | QFixed x = positions != 0 ? positions[i].x : QFixed(); never evaluated: positions != 0 | 0 |
| 96 | subPixelPosition = fontEngine->subPixelPositionForX(x); | - |
| 97 | } | 0 |
| 98 | | - |
| 99 | if (coords.contains(GlyphAndSubPixelPosition(glyph, subPixelPosition))) evaluated: coords.contains(GlyphAndSubPixelPosition(glyph, subPixelPosition))| yes Evaluation Count:21 | yes Evaluation Count:3 |
| 3-21 |
| 100 | continue; executed: continue;Execution Count:21 | 21 |
| 101 | if (listItemCoordinates.contains(GlyphAndSubPixelPosition(glyph, subPixelPosition))) evaluated: listItemCoordinates.contains(GlyphAndSubPixelPosition(glyph, subPixelPosition))| yes Evaluation Count:2 | yes Evaluation Count:1 |
| 1-2 |
| 102 | continue; executed: continue;Execution Count:2 | 2 |
| 103 | glyph_metrics_t metrics = fontEngine->alphaMapBoundingBox(glyph, subPixelPosition, m_transform, format); | - |
| 104 | GlyphAndSubPixelPosition key(glyph, subPixelPosition); | - |
| 105 | int glyph_width = metrics.width.ceil().toInt(); | - |
| 106 | int glyph_height = metrics.height.ceil().toInt(); | - |
| 107 | if (glyph_height == 0 || glyph_width == 0) { partially evaluated: glyph_height == 0| no Evaluation Count:0 | yes Evaluation Count:1 |
partially evaluated: glyph_width == 0| no Evaluation Count:0 | yes Evaluation Count:1 |
| 0-1 |
| 108 | | - |
| 109 | Coord c = { 0, 0, 0, 0, 0, 0 }; | - |
| 110 | coords.insert(key, c); | - |
| 111 | continue; never executed: continue; | 0 |
| 112 | } | - |
| 113 | glyph_width += margin * 2 + 4; | - |
| 114 | glyph_height += margin * 2 + 4; | - |
| 115 | | - |
| 116 | if (m_type == QFontEngineGlyphCache::Raster_Mono) partially evaluated: m_type == QFontEngineGlyphCache::Raster_Mono| no Evaluation Count:0 | yes Evaluation Count:1 |
| 0-1 |
| 117 | glyph_width = (glyph_width+7)&~7; never executed: glyph_width = (glyph_width+7)&~7; | 0 |
| 118 | | - |
| 119 | Coord c = { 0, 0, | - |
| 120 | glyph_width, | - |
| 121 | glyph_height, | - |
| 122 | metrics.x.truncate(), | - |
| 123 | -metrics.y.truncate() }; | - |
| 124 | | - |
| 125 | listItemCoordinates.insert(key, c); | - |
| 126 | rowHeight = qMax(rowHeight, glyph_height); | - |
| 127 | } executed: }Execution Count:1 | 1 |
| 128 | if (listItemCoordinates.isEmpty()) evaluated: listItemCoordinates.isEmpty()| yes Evaluation Count:7 | yes Evaluation Count:1 |
| 1-7 |
| 129 | return true; executed: return true;Execution Count:7 | 7 |
| 130 | | - |
| 131 | rowHeight += margin * 2 + paddingDoubled; | - |
| 132 | | - |
| 133 | if (m_w == 0) { partially evaluated: m_w == 0| yes Evaluation Count:1 | no Evaluation Count:0 |
| 0-1 |
| 134 | if (fontEngine->maxCharWidth() <= 256) partially evaluated: fontEngine->maxCharWidth() <= 256| yes Evaluation Count:1 | no Evaluation Count:0 |
| 0-1 |
| 135 | m_w = 256; executed: m_w = 256;Execution Count:1 | 1 |
| 136 | else | - |
| 137 | m_w = qt_next_power_of_two(fontEngine->maxCharWidth()); never executed: m_w = qt_next_power_of_two(fontEngine->maxCharWidth()); | 0 |
| 138 | } | - |
| 139 | | - |
| 140 | | - |
| 141 | QHash<GlyphAndSubPixelPosition, Coord>::iterator iter = listItemCoordinates.begin(); | - |
| 142 | int requiredWidth = m_w; | - |
| 143 | while (iter != listItemCoordinates.end()) { evaluated: iter != listItemCoordinates.end()| yes Evaluation Count:1 | yes Evaluation Count:1 |
| 1 |
| 144 | Coord c = iter.value(); | - |
| 145 | | - |
| 146 | m_currentRowHeight = qMax(m_currentRowHeight, c.h + margin * 2); | - |
| 147 | | - |
| 148 | if (m_cx + c.w > requiredWidth) { partially evaluated: m_cx + c.w > requiredWidth| no Evaluation Count:0 | yes Evaluation Count:1 |
| 0-1 |
| 149 | int new_width = requiredWidth*2; | - |
| 150 | while (new_width < m_cx + c.w) never evaluated: new_width < m_cx + c.w | 0 |
| 151 | new_width *= 2; never executed: new_width *= 2; | 0 |
| 152 | if (new_width <= maxTextureWidth()) { never evaluated: new_width <= maxTextureWidth() | 0 |
| 153 | requiredWidth = new_width; | - |
| 154 | } else { | 0 |
| 155 | | - |
| 156 | m_cx = 0; | - |
| 157 | m_cy += m_currentRowHeight + paddingDoubled; | - |
| 158 | m_currentRowHeight = c.h + margin * 2; | - |
| 159 | } | 0 |
| 160 | } | - |
| 161 | | - |
| 162 | if (maxTextureHeight() > 0 && m_cy + c.h > maxTextureHeight()) { partially evaluated: maxTextureHeight() > 0| no Evaluation Count:0 | yes Evaluation Count:1 |
never evaluated: m_cy + c.h > maxTextureHeight() | 0-1 |
| 163 | | - |
| 164 | return false; never executed: return false; | 0 |
| 165 | } | - |
| 166 | | - |
| 167 | c.x = m_cx; | - |
| 168 | c.y = m_cy; | - |
| 169 | | - |
| 170 | coords.insert(iter.key(), c); | - |
| 171 | m_pendingGlyphs.insert(iter.key(), c); | - |
| 172 | | - |
| 173 | m_cx += c.w + paddingDoubled; | - |
| 174 | ++iter; | - |
| 175 | } executed: }Execution Count:1 | 1 |
| 176 | return true; executed: return true;Execution Count:1 | 1 |
| 177 | | - |
| 178 | } | - |
| 179 | | - |
| 180 | void QTextureGlyphCache::fillInPendingGlyphs() | - |
| 181 | { | - |
| 182 | if (m_pendingGlyphs.isEmpty()) evaluated: m_pendingGlyphs.isEmpty()| yes Evaluation Count:7 | yes Evaluation Count:1 |
| 1-7 |
| 183 | return; executed: return;Execution Count:7 | 7 |
| 184 | | - |
| 185 | int requiredHeight = m_h; | - |
| 186 | int requiredWidth = m_w; | - |
| 187 | { | - |
| 188 | QHash<GlyphAndSubPixelPosition, Coord>::iterator iter = m_pendingGlyphs.begin(); | - |
| 189 | while (iter != m_pendingGlyphs.end()) { evaluated: iter != m_pendingGlyphs.end()| yes Evaluation Count:1 | yes Evaluation Count:1 |
| 1 |
| 190 | Coord c = iter.value(); | - |
| 191 | requiredHeight = qMax(requiredHeight, c.y + c.h); | - |
| 192 | requiredWidth = qMax(requiredWidth, c.x + c.w); | - |
| 193 | ++iter; | - |
| 194 | } executed: }Execution Count:1 | 1 |
| 195 | } | - |
| 196 | | - |
| 197 | if (isNull() || requiredHeight > m_h || requiredWidth > m_w) { partially evaluated: isNull()| yes Evaluation Count:1 | no Evaluation Count:0 |
never evaluated: requiredHeight > m_h never evaluated: requiredWidth > m_w | 0-1 |
| 198 | if (isNull()) partially evaluated: isNull()| yes Evaluation Count:1 | no Evaluation Count:0 |
| 0-1 |
| 199 | createCache(qt_next_power_of_two(requiredWidth), qt_next_power_of_two(requiredHeight)); executed: createCache(qt_next_power_of_two(requiredWidth), qt_next_power_of_two(requiredHeight));Execution Count:1 | 1 |
| 200 | else | - |
| 201 | resizeCache(qt_next_power_of_two(requiredWidth), qt_next_power_of_two(requiredHeight)); never executed: resizeCache(qt_next_power_of_two(requiredWidth), qt_next_power_of_two(requiredHeight)); | 0 |
| 202 | } | - |
| 203 | | - |
| 204 | { | - |
| 205 | QHash<GlyphAndSubPixelPosition, Coord>::iterator iter = m_pendingGlyphs.begin(); | - |
| 206 | while (iter != m_pendingGlyphs.end()) { evaluated: iter != m_pendingGlyphs.end()| yes Evaluation Count:1 | yes Evaluation Count:1 |
| 1 |
| 207 | GlyphAndSubPixelPosition key = iter.key(); | - |
| 208 | fillTexture(iter.value(), key.glyph, key.subPixelPosition); | - |
| 209 | | - |
| 210 | ++iter; | - |
| 211 | } executed: }Execution Count:1 | 1 |
| 212 | } | - |
| 213 | | - |
| 214 | m_pendingGlyphs.clear(); | - |
| 215 | } executed: }Execution Count:1 | 1 |
| 216 | | - |
| 217 | QImage QTextureGlyphCache::textureMapForGlyph(glyph_t g, QFixed subPixelPosition) const | - |
| 218 | { | - |
| 219 | if (m_type == QFontEngineGlyphCache::Raster_RGBMask) partially evaluated: m_type == QFontEngineGlyphCache::Raster_RGBMask| no Evaluation Count:0 | yes Evaluation Count:1 |
| 0-1 |
| 220 | return m_current_fontengine->alphaRGBMapForGlyph(g, subPixelPosition, m_transform); never executed: return m_current_fontengine->alphaRGBMapForGlyph(g, subPixelPosition, m_transform); | 0 |
| 221 | return m_current_fontengine->alphaMapForGlyph(g, subPixelPosition, m_transform); executed: return m_current_fontengine->alphaMapForGlyph(g, subPixelPosition, m_transform);Execution Count:1 | 1 |
| 222 | } | - |
| 223 | | - |
| 224 | | - |
| 225 | | - |
| 226 | | - |
| 227 | | - |
| 228 | void QImageTextureGlyphCache::resizeTextureData(int width, int height) | - |
| 229 | { | - |
| 230 | m_image = m_image.copy(0, 0, width, height); | - |
| 231 | } | 0 |
| 232 | | - |
| 233 | void QImageTextureGlyphCache::createTextureData(int width, int height) | - |
| 234 | { | - |
| 235 | switch (m_type) { | - |
| 236 | case QFontEngineGlyphCache::Raster_Mono: | - |
| 237 | m_image = QImage(width, height, QImage::Format_Mono); | - |
| 238 | break; | 0 |
| 239 | case QFontEngineGlyphCache::Raster_A8: { | - |
| 240 | m_image = QImage(width, height, QImage::Format_Indexed8); | - |
| 241 | m_image.fill(0); | - |
| 242 | QVector<QRgb> colors(256); | - |
| 243 | QRgb *it = colors.data(); | - |
| 244 | for (int i=0; i<256; ++i, ++it) evaluated: i<256| yes Evaluation Count:256 | yes Evaluation Count:1 |
| 1-256 |
| 245 | *it = 0xff000000 | i | (i<<8) | (i<<16); executed: *it = 0xff000000 | i | (i<<8) | (i<<16);Execution Count:256 | 256 |
| 246 | m_image.setColorTable(colors); | - |
| 247 | break; } executed: break;Execution Count:1 | 1 |
| 248 | case QFontEngineGlyphCache::Raster_RGBMask: | - |
| 249 | m_image = QImage(width, height, QImage::Format_RGB32); | - |
| 250 | break; | 0 |
| 251 | case QFontEngineGlyphCache::Raster_ARGB: | - |
| 252 | break; | 0 |
| 253 | } | - |
| 254 | } executed: }Execution Count:1 | 1 |
| 255 | | - |
| 256 | void QImageTextureGlyphCache::fillTexture(const Coord &c, glyph_t g, QFixed subPixelPosition) | - |
| 257 | { | - |
| 258 | QImage mask = textureMapForGlyph(g, subPixelPosition); | - |
| 259 | if (m_type == QFontEngineGlyphCache::Raster_RGBMask) { partially evaluated: m_type == QFontEngineGlyphCache::Raster_RGBMask| no Evaluation Count:0 | yes Evaluation Count:1 |
| 0-1 |
| 260 | QImage ref(m_image.bits() + (c.x * 4 + c.y * m_image.bytesPerLine()), | - |
| 261 | qMax(mask.width(), c.w), qMax(mask.height(), c.h), m_image.bytesPerLine(), | - |
| 262 | m_image.format()); | - |
| 263 | QPainter p(&ref); | - |
| 264 | p.setCompositionMode(QPainter::CompositionMode_Source); | - |
| 265 | p.fillRect(0, 0, c.w, c.h, QColor(0,0,0,0)); | - |
| 266 | p.drawImage(0, 0, mask); | - |
| 267 | p.end(); | - |
| 268 | } else if (m_type == QFontEngineGlyphCache::Raster_Mono) { partially evaluated: m_type == QFontEngineGlyphCache::Raster_Mono| no Evaluation Count:0 | yes Evaluation Count:1 |
| 0-1 |
| 269 | if (mask.depth() > 1) { never evaluated: mask.depth() > 1 | 0 |
| 270 | | - |
| 271 | mask = mask.alphaChannel(); | - |
| 272 | mask.invertPixels(); | - |
| 273 | mask = mask.convertToFormat(QImage::Format_Mono); | - |
| 274 | } | 0 |
| 275 | | - |
| 276 | int mw = qMin(mask.width(), c.w); | - |
| 277 | int mh = qMin(mask.height(), c.h); | - |
| 278 | uchar *d = m_image.bits(); | - |
| 279 | int dbpl = m_image.bytesPerLine(); | - |
| 280 | | - |
| 281 | for (int y = 0; y < c.h; ++y) { | 0 |
| 282 | uchar *dest = d + (c.y + y) *dbpl + c.x/8; | - |
| 283 | | - |
| 284 | if (y < mh) { | 0 |
| 285 | uchar *src = mask.scanLine(y); | - |
| 286 | for (int x = 0; x < c.w/8; ++x) { never evaluated: x < c.w/8 | 0 |
| 287 | if (x < (mw+7)/8) never evaluated: x < (mw+7)/8 | 0 |
| 288 | dest[x] = src[x]; never executed: dest[x] = src[x]; | 0 |
| 289 | else | - |
| 290 | dest[x] = 0; never executed: dest[x] = 0; | 0 |
| 291 | } | - |
| 292 | } else { | 0 |
| 293 | for (int x = 0; x < c.w/8; ++x) never evaluated: x < c.w/8 | 0 |
| 294 | dest[x] = 0; never executed: dest[x] = 0; | 0 |
| 295 | } | 0 |
| 296 | } | - |
| 297 | } else { | 0 |
| 298 | int mw = qMin(mask.width(), c.w); | - |
| 299 | int mh = qMin(mask.height(), c.h); | - |
| 300 | uchar *d = m_image.bits(); | - |
| 301 | int dbpl = m_image.bytesPerLine(); | - |
| 302 | | - |
| 303 | if (mask.depth() == 1) { partially evaluated: mask.depth() == 1| no Evaluation Count:0 | yes Evaluation Count:1 |
| 0-1 |
| 304 | for (int y = 0; y < c.h; ++y) { | 0 |
| 305 | uchar *dest = d + (c.y + y) *dbpl + c.x; | - |
| 306 | if (y < mh) { | 0 |
| 307 | uchar *src = (uchar *) mask.scanLine(y); | - |
| 308 | for (int x = 0; x < c.w; ++x) { | 0 |
| 309 | if (x < mw) | 0 |
| 310 | dest[x] = (src[x >> 3] & (1 << (7 - (x & 7)))) > 0 ? 255 : 0; never evaluated: (src[x >> 3] & (1 << (7 - (x & 7)))) > 0 never executed: dest[x] = (src[x >> 3] & (1 << (7 - (x & 7)))) > 0 ? 255 : 0; | 0 |
| 311 | } | 0 |
| 312 | } | 0 |
| 313 | } | 0 |
| 314 | } else if (mask.depth() == 8) { partially evaluated: mask.depth() == 8| yes Evaluation Count:1 | no Evaluation Count:0 |
| 0-1 |
| 315 | for (int y = 0; y < c.h; ++y) { evaluated: y < c.h| yes Evaluation Count:17 | yes Evaluation Count:1 |
| 1-17 |
| 316 | uchar *dest = d + (c.y + y) *dbpl + c.x; | - |
| 317 | if (y < mh) { evaluated: y < mh| yes Evaluation Count:13 | yes Evaluation Count:4 |
| 4-13 |
| 318 | uchar *src = (uchar *) mask.scanLine(y); | - |
| 319 | for (int x = 0; x < c.w; ++x) { evaluated: x < c.w| yes Evaluation Count:221 | yes Evaluation Count:13 |
| 13-221 |
| 320 | if (x < mw) evaluated: x < mw| yes Evaluation Count:169 | yes Evaluation Count:52 |
| 52-169 |
| 321 | dest[x] = src[x]; executed: dest[x] = src[x];Execution Count:169 | 169 |
| 322 | } executed: }Execution Count:221 | 221 |
| 323 | } executed: }Execution Count:13 | 13 |
| 324 | } executed: }Execution Count:17 | 17 |
| 325 | } executed: }Execution Count:1 | 1 |
| 326 | } | - |
| 327 | } | - |
| 328 | | - |
| 329 | | - |
| 330 | | - |
| | |