| 50 | | 'blueFuzz': {'default': None, 'max':1}, |
|---|
| 51 | | 'blueScale': {'default': None, 'max':1}, |
|---|
| 52 | | 'blueShift': {'default': None, 'max':1}, |
|---|
| 53 | | 'forceBold': {'default': None, 'max':1}, |
|---|
| 54 | | 'blueValues': {'default': None, 'max':13}, |
|---|
| 55 | | 'otherBlues': {'default': None, 'max':9}, |
|---|
| 56 | | 'familyBlues': {'default': None, 'max':13}, |
|---|
| 57 | | 'familyOtherBlues': {'default': None, 'max':9}, |
|---|
| 58 | | 'vStems': {'default': None, 'max':11}, |
|---|
| 59 | | 'hStems': {'default': None, 'max':11}, |
|---|
| | 69 | 'blueFuzz': {'default': None, 'max':1}, |
|---|
| | 70 | 'blueScale': {'default': None, 'max':1}, |
|---|
| | 71 | 'blueShift': {'default': None, 'max':1}, |
|---|
| | 72 | 'forceBold': {'default': None, 'max':1}, |
|---|
| | 73 | 'blueValues': {'default': None, 'max':7}, |
|---|
| | 74 | 'otherBlues': {'default': None, 'max':5}, |
|---|
| | 75 | 'familyBlues': {'default': None, 'max':7}, |
|---|
| | 76 | 'familyOtherBlues': {'default': None, 'max':5}, |
|---|
| | 77 | 'vStems': {'default': None, 'max':6}, |
|---|
| | 78 | 'hStems': {'default': None, 'max':11}, |
|---|
| | 122 | |
|---|
| | 123 | def copy(self, aParent=None): |
|---|
| | 124 | """Duplicate this object. Pass an object for parenting if you want.""" |
|---|
| | 125 | n = self.__class__(data=self.asDict()) |
|---|
| | 126 | if aParent is not None: |
|---|
| | 127 | n.setParent(aParent) |
|---|
| | 128 | elif self.getParent() is not None: |
|---|
| | 129 | n.setParent(self.getParent()) |
|---|
| | 130 | dont = ['getParent'] |
|---|
| | 131 | for k in self.__dict__.keys(): |
|---|
| | 132 | if k in dont: |
|---|
| | 133 | continue |
|---|
| | 134 | dup = copy.deepcopy(self.__dict__[k]) |
|---|
| | 135 | setattr(n, k, dup) |
|---|
| | 136 | return n |
|---|
| | 137 | |
|---|
| | 138 | def round(self): |
|---|
| | 139 | """Round the values to reasonable values. |
|---|
| | 140 | - blueScale is not rounded, it is a float |
|---|
| | 141 | - forceBold is set to False if -0.5 < value < 0.5. Otherwise it will be True. |
|---|
| | 142 | - blueShift, blueFuzz are rounded to int |
|---|
| | 143 | - stems are rounded to int |
|---|
| | 144 | - blues are rounded to int |
|---|
| | 145 | """ |
|---|
| | 146 | for name, values in self._attributeNames.items(): |
|---|
| | 147 | if name == "blueScale": |
|---|
| | 148 | continue |
|---|
| | 149 | elif name == "forceBold": |
|---|
| | 150 | v = getattr(self, name) |
|---|
| | 151 | if v is None: |
|---|
| | 152 | continue |
|---|
| | 153 | if -0.5 <= v <= 0.5: |
|---|
| | 154 | setattr(self, name, False) |
|---|
| | 155 | else: |
|---|
| | 156 | setattr(self, name, True) |
|---|
| | 157 | elif name in ['blueFuzz', 'blueShift']: |
|---|
| | 158 | v = getattr(self, name) |
|---|
| | 159 | if v is None: |
|---|
| | 160 | continue |
|---|
| | 161 | setattr(self, name, int(round(v))) |
|---|
| | 162 | elif name in ['hStems', 'vStems']: |
|---|
| | 163 | v = getattr(self, name) |
|---|
| | 164 | if v is None: |
|---|
| | 165 | continue |
|---|
| | 166 | new = [] |
|---|
| | 167 | for n in v: |
|---|
| | 168 | new.append(int(round(n))) |
|---|
| | 169 | setattr(self, name, new) |
|---|
| | 170 | else: |
|---|
| | 171 | v = getattr(self, name) |
|---|
| | 172 | if v is None: |
|---|
| | 173 | continue |
|---|
| | 174 | new = [] |
|---|
| | 175 | for n in v: |
|---|
| | 176 | new.append([int(round(m)) for m in n]) |
|---|
| | 177 | setattr(self, name, new) |
|---|
| | 178 | |
|---|
| | 179 | # math operations for psHint object |
|---|
| | 180 | def __add__(self, other): |
|---|
| | 181 | assert isinstance(other, BasePostScriptFontHintValues) |
|---|
| | 182 | copied = self.copy() |
|---|
| | 183 | self._processMathOne(copied, other, add) |
|---|
| | 184 | return copied |
|---|
| | 185 | |
|---|
| | 186 | def __sub__(self, other): |
|---|
| | 187 | assert isinstance(other, BasePostScriptFontHintValues) |
|---|
| | 188 | copied = self.copy() |
|---|
| | 189 | self._processMathOne(copied, other, sub) |
|---|
| | 190 | return copied |
|---|
| | 191 | |
|---|
| | 192 | def __mul__(self, factor): |
|---|
| | 193 | if isinstance(factor, tuple): |
|---|
| | 194 | factor = factor[0] |
|---|
| | 195 | copiedInfo = self.copy() |
|---|
| | 196 | self._processMathTwo(copiedInfo, factor, mul) |
|---|
| | 197 | return copiedInfo |
|---|
| | 198 | |
|---|
| | 199 | __rmul__ = __mul__ |
|---|
| | 200 | |
|---|
| | 201 | def __div__(self, factor): |
|---|
| | 202 | if isinstance(factor, tuple): |
|---|
| | 203 | factor = factor[0] |
|---|
| | 204 | copiedInfo = self.copy() |
|---|
| | 205 | self._processMathTwo(copiedInfo, factor, mul) |
|---|
| | 206 | return copiedInfo |
|---|
| | 207 | |
|---|
| | 208 | __rdiv__ = __div__ |
|---|
| | 209 | |
|---|
| | 210 | def _processMathOne(self, copied, other, funct): |
|---|
| | 211 | for name, values in self._attributeNames.items(): |
|---|
| | 212 | a = None |
|---|
| | 213 | b = None |
|---|
| | 214 | v = None |
|---|
| | 215 | if hasattr(copied, name): |
|---|
| | 216 | a = getattr(copied, name) |
|---|
| | 217 | if hasattr(other, name): |
|---|
| | 218 | b = getattr(other, name) |
|---|
| | 219 | if name in ['blueFuzz', 'blueScale', 'blueShift', 'forceBold']: |
|---|
| | 220 | # process single values |
|---|
| | 221 | if a is not None and b is not None: |
|---|
| | 222 | v = funct(a, b) |
|---|
| | 223 | elif a is not None and b is None: |
|---|
| | 224 | v = a |
|---|
| | 225 | elif b is not None and a is None: |
|---|
| | 226 | v = b |
|---|
| | 227 | if v is not None: |
|---|
| | 228 | setattr(copied, name, v) |
|---|
| | 229 | elif name in ['hStems', 'vStems']: |
|---|
| | 230 | if a is not None and b is not None: |
|---|
| | 231 | l = min(len(a), len(b)) |
|---|
| | 232 | v = [funct(a[i], b[i]) for i in range(l)] |
|---|
| | 233 | if v is not None: |
|---|
| | 234 | setattr(copied, name, v) |
|---|
| | 235 | else: |
|---|
| | 236 | if a is not None and b is not None: |
|---|
| | 237 | l = min(len(a), len(b)) |
|---|
| | 238 | for i in range(l): |
|---|
| | 239 | if v is None: |
|---|
| | 240 | v = [] |
|---|
| | 241 | ai = a[i] |
|---|
| | 242 | bi = b[i] |
|---|
| | 243 | l2 = min(len(ai), len(bi)) |
|---|
| | 244 | v2 = [funct(ai[j], bi[j]) for j in range(l2)] |
|---|
| | 245 | v.append(v2) |
|---|
| | 246 | if v is not None: |
|---|
| | 247 | setattr(copied, name, v) |
|---|
| | 248 | |
|---|
| | 249 | def _processMathTwo(self, copied, factor, funct): |
|---|
| | 250 | for name, values in self._attributeNames.items(): |
|---|
| | 251 | a = None |
|---|
| | 252 | b = None |
|---|
| | 253 | v = None |
|---|
| | 254 | if hasattr(copied, name): |
|---|
| | 255 | a = getattr(copied, name) |
|---|
| | 256 | if name in ['blueFuzz', 'blueScale', 'blueShift', 'forceBold']: |
|---|
| | 257 | # process single values |
|---|
| | 258 | if a is not None: |
|---|
| | 259 | v = funct(a, factor) |
|---|
| | 260 | if v is not None: |
|---|
| | 261 | setattr(copied, name, v) |
|---|
| | 262 | elif name in ['hStems', 'vStems']: |
|---|
| | 263 | if a is not None: |
|---|
| | 264 | v = [funct(a[i], factor) for i in range(len(a))] |
|---|
| | 265 | if v is not None: |
|---|
| | 266 | setattr(copied, name, v) |
|---|
| | 267 | else: |
|---|
| | 268 | if a is not None: |
|---|
| | 269 | for i in range(len(a)): |
|---|
| | 270 | if v is None: |
|---|
| | 271 | v = [] |
|---|
| | 272 | v2 = [funct(a[i][j], factor) for j in range(len(a[i]))] |
|---|
| | 273 | v.append(v2) |
|---|
| | 274 | if v is not None: |
|---|
| | 275 | setattr(copied, name, v) |
|---|
| | 276 | |
|---|