File indexing completed on 2024-11-10 09:38:52
0001 /* 0002 * This file is part of the html renderer for KDE. 0003 * 0004 * Copyright (C) 2000-2003 Lars Knoll (knoll@kde.org) 0005 * (C) 2000 Antti Koivisto (koivisto@kde.org) 0006 * (C) 2000 Dirk Mueller (mueller@kde.org) 0007 * 0008 * This library is free software; you can redistribute it and/or 0009 * modify it under the terms of the GNU Library General Public 0010 * License as published by the Free Software Foundation; either 0011 * version 2 of the License, or (at your option) any later version. 0012 * 0013 * This library is distributed in the hope that it will be useful, 0014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0016 * Library General Public License for more details. 0017 * 0018 * You should have received a copy of the GNU Library General Public License 0019 * along with this library; see the file COPYING.LIB. If not, write to 0020 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0021 * Boston, MA 02110-1301, USA. 0022 * 0023 */ 0024 0025 #ifndef KHTMLFONT_H 0026 #define KHTMLFONT_H 0027 0028 #include <khtml_global.h> 0029 #include <khtml_settings.h> 0030 0031 #include <QCache> 0032 #include <QFont> 0033 #include <QFontMetrics> 0034 #include <QPainter> 0035 0036 #include "misc/shared.h" 0037 0038 namespace DOM 0039 { 0040 class DOMString; 0041 } 0042 0043 namespace khtml 0044 { 0045 class RenderStyle; 0046 class CSSStyleSelector; 0047 0048 class CachedFontFamily; 0049 0050 class CachedFontInstance: public Shared<CachedFontInstance> 0051 { 0052 public: 0053 CachedFontInstance(CachedFontFamily *parent, int size); 0054 0055 QFont f; 0056 QFontMetrics fm; // note:stuff below is faster when applicable. 0057 // Also, do not rearrange these two fields --- one neefs f to initialize fm 0058 0059 // We store cached width metrics as a two-level tree --- 0060 // top-level is row for the codepoint, second is column. 0061 // Some rows may have no information on them. 0062 // For a cell, value 255 means no known width (or a width >= 255) 0063 unsigned cachedCharWidth(unsigned short codePoint) 0064 { 0065 unsigned width = 0xFF; 0066 if (RowInfo *row = rows[codePoint >> 8]) { 0067 width = row->widths[codePoint & 0xFF]; 0068 } 0069 if (width != 0xFF) { 0070 return width; 0071 } else { 0072 return calcAndCacheWidth(codePoint); 0073 } 0074 } 0075 0076 unsigned cachedCharWidth(const QChar &c) 0077 { 0078 return cachedCharWidth(c.unicode()); 0079 } 0080 0081 // query again all metrics 0082 void invalidate(); 0083 0084 // Simple cached metrics, set on creation 0085 int ascent; 0086 int descent; 0087 int height; 0088 int lineSpacing; 0089 int xHeight; 0090 int m_zeroCharWidth; 0091 mutable bool invalidated; 0092 0093 ~CachedFontInstance(); 0094 private: 0095 unsigned calcAndCacheWidth(unsigned short codePoint); 0096 0097 struct RowInfo { 0098 unsigned char widths[256]; 0099 0100 RowInfo() 0101 { 0102 for (int i = 0; i < 256; ++i) { 0103 widths[i] = 0xFF; 0104 } 0105 } 0106 }; 0107 0108 RowInfo *rows[256]; 0109 CachedFontFamily *parent; 0110 int size; // the size we were created with 0111 }; 0112 0113 class FontDef 0114 { 0115 public: 0116 FontDef() 0117 : family(KHTMLGlobal::defaultHTMLSettings()->stdFontName()), size(0), italic(false), smallCaps(false), weight(QFont::Normal) {} 0118 bool operator == (const FontDef &other) const 0119 { 0120 return (family == other.family && 0121 size == other.size && 0122 italic == other.italic && 0123 smallCaps == other.smallCaps && 0124 weight == other.weight); 0125 } 0126 0127 QString family; 0128 short int size; 0129 bool italic : 1; 0130 bool smallCaps : 1; 0131 unsigned int weight : 8; 0132 }; 0133 0134 class Font 0135 { 0136 friend class RenderStyle; 0137 friend class CSSStyleSelector; 0138 0139 static CachedFontInstance *defaultCFI; 0140 public: 0141 static void initDefault(); 0142 0143 Font() : fontDef(), cfi(defaultCFI), scFont(nullptr), letterSpacing(0), wordSpacing(0) {} 0144 Font(const FontDef &fd) 0145 : fontDef(fd), cfi(defaultCFI), scFont(nullptr), letterSpacing(0), wordSpacing(0) 0146 {} 0147 Font(const Font &o) 0148 : fontDef(o.fontDef), cfi(o.cfi), scFont(o.scFont), letterSpacing(o.letterSpacing), wordSpacing(o.wordSpacing) 0149 { 0150 if (o.scFont) { 0151 scFont = new QFont(*o.scFont); 0152 } 0153 } 0154 ~Font() 0155 { 0156 delete scFont; 0157 } 0158 0159 bool operator == (const Font &other) const 0160 { 0161 return (fontDef == other.fontDef && 0162 letterSpacing == other.letterSpacing && 0163 wordSpacing == other.wordSpacing); 0164 } 0165 0166 const FontDef &getFontDef() const 0167 { 0168 return fontDef; 0169 } 0170 0171 void update(int logicalDpiY) const; 0172 0173 static void invalidateCachedFontFamily(const QString &familyName); 0174 static void markAllCachedFontsAsValid(); 0175 0176 /** 0177 * Draws a piece from the given piece of text. 0178 * @param p painter 0179 * @param x x-coordinate to begin drawing, always denotes leftmost position 0180 * @param y y-coordinate of baseline of text 0181 * @param str string to draw a piece from 0182 * @param slen total length of string 0183 * @param pos zero-based offset of beginning of piece 0184 * @param len length of piece 0185 * @param width additional pixels to be distributed equally among all 0186 * spaces 0187 * @param d text direction 0188 * @param from begin with this position relative to @p pos, -1 to start 0189 * at @p pos 0190 * @param to stop before this position relative to @p pos, -1 to use full 0191 * length of piece 0192 * @param bg if valid, fill the background of the drawn piece with this 0193 * color 0194 * @param uy y-coordinate of top position, used for background and text 0195 * decoration painting 0196 * @param h total height of line, only used for background and text 0197 * decoration painting 0198 * @param deco combined text decoration (see Decoration) 0199 */ 0200 void drawText(QPainter *p, int x, int y, const QChar *str, const int slen, int pos, int len, int width, 0201 Qt::LayoutDirection d, int from = -1, int to = -1, QColor bg = QColor(), 0202 int uy = -1, int h = -1, int deco = 0) const; 0203 0204 /** returns the width of the given string chunk in pixels. 0205 * 0206 * The method also considers various styles like text-align and font-variant 0207 * @param str pointer to string 0208 * @param slen total length of string 0209 * @param pos zero-based position in string where to start measuring 0210 * @param len count of characters up to which the width should be determined 0211 * @param fast Use simplest/fastest algorithm (for e.g strings without special/combining chars) 0212 * @param start starting position of inline text box within str, only 0213 * used when toAdd is specified. 0214 * @param end ending position of inline text box within str, only 0215 * used when toAdd is specified. 0216 * @param toAdd amount of pixels to distribute evenly among all spaces of 0217 * str. Note that toAdd applies to all spaces within str, but only those 0218 * within [pos, pos+len) are counted towards the width. 0219 */ 0220 int width(const QChar *str, int slen, int pos, int len, bool fast, int start = 0, int end = 0, int toAdd = 0) const; 0221 /** return the width of the given char in pixels. 0222 * 0223 * The method also considers various styles like text-align and font-variant 0224 * @param str pointer to string 0225 * @param slen total length of string 0226 * @param pos zero-based position of char in string 0227 */ 0228 int charWidth(const QChar *str, int slen, int pos, bool fast) const; 0229 0230 /** Text decoration constants. 0231 * 0232 * The enumeration constant values match those of ETextDecoration, but only 0233 * a subset is supported. 0234 */ 0235 enum Decoration { UNDERLINE = 0x1, OVERLINE = 0x2, LINE_THROUGH = 0x4 }; 0236 // Keep in sync with ETextDecoration 0237 0238 /** draws text decoration 0239 * @param p painter 0240 * @param x x-coordinate 0241 * @param y top y-coordinate of line box 0242 * @param baseline baseline 0243 * @param width length of decoration in pixels 0244 * @param height height of line box 0245 * @param deco decoration to be drawn (see Decoration). The enumeration 0246 * constants may be combined. 0247 */ 0248 void drawDecoration(QPainter *p, int x, int y, int baseline, int width, int height, int deco) const; 0249 0250 /** returns letter spacing 0251 */ 0252 int getLetterSpacing() const 0253 { 0254 return letterSpacing; 0255 } 0256 /** returns word spacing 0257 */ 0258 int getWordSpacing() const 0259 { 0260 return wordSpacing; 0261 } 0262 0263 // for SVG 0264 int ascent() const 0265 { 0266 return cfi->ascent; 0267 } 0268 int descent() const 0269 { 0270 return cfi->descent; 0271 } 0272 int height() const 0273 { 0274 return cfi->height; 0275 } 0276 int lineSpacing() const 0277 { 0278 return cfi->lineSpacing; 0279 } 0280 int xHeight() const 0281 { 0282 return cfi->xHeight; 0283 } 0284 0285 // return -1 if '0' char glyph not in font 0286 int zeroCharWidth() const 0287 { 0288 return cfi->m_zeroCharWidth; 0289 } 0290 //FIXME: IMPLEMENT ME 0291 unsigned unitsPerEm() const 0292 { 0293 return 0; 0294 } 0295 int spaceWidth() const 0296 { 0297 return 0; 0298 } 0299 int tabWidth() const 0300 { 0301 return 8 * spaceWidth(); 0302 } 0303 0304 bool isInvalidated() const 0305 { 0306 return cfi->invalidated; 0307 } 0308 void validate() const 0309 { 0310 cfi->invalidated = false; 0311 } 0312 0313 // SVG helper function 0314 float floatWidth(QChar *str, int pos, int len, int extraCharsAvailable, int &charsConsumed, DOM::DOMString &glyphName) const; 0315 0316 float floatWidth(QChar *str, int pos, int len) const; 0317 0318 private: 0319 static CachedFontFamily *queryFamily(const QString &name, int weight, bool italic); 0320 0321 mutable FontDef fontDef; 0322 mutable WTF::SharedPtr<CachedFontInstance> cfi; 0323 mutable QFont *scFont; 0324 short letterSpacing; 0325 short wordSpacing; 0326 }; 0327 0328 } // namespace 0329 0330 #endif