def textSearch(self, txt, box, search, align): canHyphenate = True if isinstance(box, self._bezierPathClass): canHyphenate = False path = box._getCGPath() (x, y), (w, h) = CoreText.CGPathGetPathBoundingBox(path) else: x, y, w, h = box path = CoreText.CGPathCreateMutable() CoreText.CGPathAddRect(path, None, CoreText.CGRectMake(x, y, w, h)) canDoGradients = True attrString = self.attributedString(txt, align=align) if canHyphenate and self._state.hyphenation: attrString = self.hyphenateAttributedString(attrString, w) txt = attrString.string() searchRE = re.compile(search) locations = [] for found in searchRE.finditer(txt): locations.append((found.start(), found.end())) setter = CoreText.CTFramesetterCreateWithAttributedString(attrString) box = CoreText.CTFramesetterCreateFrame(setter, (0, 0), path, None) ctLines = CoreText.CTFrameGetLines(box) origins = CoreText.CTFrameGetLineOrigins(box, (0, len(ctLines)), None) rectangles = [] for startLocation, endLocation in locations: minx = miny = maxx = maxy = None for i, (originX, originY) in enumerate(origins): ctLine = ctLines[i] bounds = CoreText.CTLineGetImageBounds(ctLine, None) if bounds.size.width == 0: continue _, ascent, descent, leading = CoreText.CTLineGetTypographicBounds( ctLine, None, None, None) height = ascent + descent lineRange = CoreText.CTLineGetStringRange(ctLine) miny = maxy = originY if AppKit.NSLocationInRange(startLocation, lineRange): minx, _ = CoreText.CTLineGetOffsetForStringIndex( ctLine, startLocation, None) if AppKit.NSLocationInRange(endLocation, lineRange): maxx, _ = CoreText.CTLineGetOffsetForStringIndex( ctLine, endLocation, None) rectangles.append( (x + minx, y + miny - descent, maxx - minx, height)) if minx and maxx is None: rectangles.append((x + minx, y + miny - descent, bounds.size.width - minx, height)) minx = 0 return rectangles
def _getPathForFrameSetter(self, box): if isinstance(box, BezierPath): path = box._getCGPath() (x, y), (w, h) = CoreText.CGPathGetPathBoundingBox(path) else: x, y, w, h = box path = CoreText.CGPathCreateMutable() CoreText.CGPathAddRect(path, None, CoreText.CGRectMake(x, y, w, h)) return path, (x, y)