Beispiel #1
0
    def test_sameFrag(self):
        from _rl_accel import _sameFrag
        class ABag:
            def __init__(self,**kwd):
                self.__dict__.update(kwd)
            def __str__(self):
                V=['%s=%r' % v for v in self.__dict__.items()]
                V.sort()
                return 'ABag(%s)' % ','.join(V)

        a=ABag(fontName='Helvetica',fontSize=12, textColor="red", rise=0, underline=0, strike=0, link="aaaa")
        b=ABag(fontName='Helvetica',fontSize=12, textColor="red", rise=0, underline=0, strike=0, link="aaaa")
        for name in ("fontName", "fontSize", "textColor", "rise", "underline", "strike", "link"):
            old = getattr(a,name)
            assert _sameFrag(a,b)==1, "_sameFrag(%s,%s)!=1" % (a,b)
            assert _sameFrag(b,a)==1, "_sameFrag(%s,%s)!=1" % (b,a)
            setattr(a,name,None)
            assert _sameFrag(a,b)==0, "_sameFrag(%s,%s)!=0" % (a,b)
            assert _sameFrag(b,a)==0, "_sameFrag(%s,%s)!=0" % (b,a)
            delattr(a,name)
            assert _sameFrag(a,b)==0, "_sameFrag(%s,%s)!=0" % (a,b)
            assert _sameFrag(b,a)==0, "_sameFrag(%s,%s)!=0" % (b,a)
            delattr(b,name)
            assert _sameFrag(a,b)==1, "_sameFrag(%s,%s)!=1" % (a,b)
            assert _sameFrag(b,a)==1, "_sameFrag(%s,%s)!=1" % (b,a)
            setattr(a,name,old)
            setattr(b,name,old)
Beispiel #2
0
    def breakLines(self, width):
        """
        Returns a broken line structure. There are two cases

        A) For the simple case of a single formatting input fragment the output is
            A fragment specifier with
                kind = 0
                fontName, fontSize, leading, textColor
                lines=  A list of lines
                        Each line has two items.
                        1) unused width in points
                        2) word list

        B) When there is more than one input formatting fragment the output is
            A fragment specifier with
                kind = 1
                lines=  A list of fragments each having fields
                            extraspace (needed for justified)
                            fontSize
                            words=word list
                                each word is itself a fragment with
                                various settings

        This structure can be used to easily draw paragraphs with the various alignments.
        You can supply either a single width or a list of widths; the latter will have its
        last item repeated until necessary. A 2-element list is useful when there is a
        different first line indent; a longer list could be created to facilitate custom wraps
        around irregular objects."""

        if type(width) <> ListType: maxWidths = [width]
        else: maxWidths = width
        lines = []
        lineno = 0
        style = self.style
        fFontSize = float(style.fontSize)

        #for bullets, work out width and ensure we wrap the right amount onto line one
        _handleBulletWidth(self.bulletText, style, maxWidths)

        maxWidth = maxWidths[0]

        self.height = 0
        frags = self.frags
        nFrags = len(frags)
        if nFrags == 1 and not hasattr(frags[0], 'cbDefn'):
            f = frags[0]
            fontSize = f.fontSize
            fontName = f.fontName
            words = hasattr(f, 'text') and split(f.text, ' ') or f.words
            spaceWidth = stringWidth(' ', fontName, fontSize, self.encoding)
            cLine = []
            currentWidth = -spaceWidth  # hack to get around extra space for word 1
            for word in words:
                #this underscores my feeling that Unicode throughout would be easier!
                wordWidth = stringWidth(word, fontName, fontSize,
                                        self.encoding)
                newWidth = currentWidth + spaceWidth + wordWidth
                if newWidth <= maxWidth or not len(cLine):
                    # fit one more on this line
                    cLine.append(word)
                    currentWidth = newWidth
                else:
                    if currentWidth > self.width: self.width = currentWidth
                    #end of line
                    lines.append((maxWidth - currentWidth, cLine))
                    cLine = [word]
                    currentWidth = wordWidth
                    lineno += 1
                    try:
                        maxWidth = maxWidths[lineno]
                    except IndexError:
                        maxWidth = maxWidths[-1]  # use the last one

            #deal with any leftovers on the final line
            if cLine != []:
                if currentWidth > self.width: self.width = currentWidth
                lines.append((maxWidth - currentWidth, cLine))

            return f.clone(kind=0, lines=lines)
        elif nFrags <= 0:
            return ParaLines(kind=0,
                             fontSize=style.fontSize,
                             fontName=style.fontName,
                             textColor=style.textColor,
                             lines=[])
        else:
            if hasattr(self, 'blPara') and getattr(self, '_splitpara', 0):
                #NB this is an utter hack that awaits the proper information
                #preserving splitting algorithm
                return self.blPara
            n = 0
            words = []
            for w in _getFragWords(frags):
                spaceWidth = stringWidth(' ', w[-1][0].fontName,
                                         w[-1][0].fontSize)

                if n == 0:
                    currentWidth = -spaceWidth  # hack to get around extra space for word 1
                    maxSize = 0

                wordWidth = w[0]
                f = w[1][0]
                if wordWidth > 0:
                    newWidth = currentWidth + spaceWidth + wordWidth
                else:
                    newWidth = currentWidth

                #test to see if this frag is a line break. If it is we will only act on it
                #if the current width is non-negative or the previous thing was a deliberate lineBreak
                lineBreak = hasattr(f, 'lineBreak')
                endLine = (newWidth > maxWidth and n > 0) or lineBreak
                if not endLine:
                    if lineBreak: continue  #throw it away
                    nText = w[1][1]
                    if nText: n += 1
                    maxSize = max(maxSize, f.fontSize)
                    if words == []:
                        g = f.clone()
                        words = [g]
                        g.text = nText
                    elif not _sameFrag(g, f):
                        if currentWidth > 0 and (
                            (nText != '' and nText[0] != ' ')
                                or hasattr(f, 'cbDefn')):
                            if hasattr(g, 'cbDefn'):
                                i = len(words) - 1
                                while hasattr(words[i], 'cbDefn'):
                                    i -= 1
                                words[i].text += ' '
                            else:
                                g.text += ' '
                        g = f.clone()
                        words.append(g)
                        g.text = nText
                    else:
                        if nText != '' and nText[0] != ' ':
                            g.text += ' ' + nText

                    for i in w[2:]:
                        g = i[0].clone()
                        g.text = i[1]
                        words.append(g)
                        maxSize = max(maxSize, g.fontSize)

                    currentWidth = newWidth
                else:  #either it won't fit, or it's a lineBreak tag
                    if lineBreak:
                        g = f.clone()
                        #del g.lineBreak
                        words.append(g)

                    if currentWidth > self.width: self.width = currentWidth
                    #end of line
                    lines.append(
                        FragLine(extraSpace=(maxWidth - currentWidth),
                                 wordCount=n,
                                 words=words,
                                 fontSize=maxSize))

                    #start new line
                    lineno += 1
                    try:
                        maxWidth = maxWidths[lineno]
                    except IndexError:
                        maxWidth = maxWidths[-1]  # use the last one

                    if lineBreak:
                        n = 0
                        words = []
                        continue

                    currentWidth = wordWidth
                    n = 1
                    maxSize = f.fontSize
                    g = f.clone()
                    words = [g]
                    g.text = w[1][1]

                    for i in w[2:]:
                        g = i[0].clone()
                        g.text = i[1]
                        words.append(g)
                        maxSize = max(maxSize, g.fontSize)

            #deal with any leftovers on the final line
            if words != []:
                if currentWidth > self.width: self.width = currentWidth
                lines.append(
                    ParaLines(extraSpace=(maxWidth - currentWidth),
                              wordCount=n,
                              words=words,
                              fontSize=maxSize))
            return ParaLines(kind=1, lines=lines)

        return lines
Beispiel #3
0
    def breakLines(self, width):
        """
        Returns a broken line structure. There are two cases

        A) For the simple case of a single formatting input fragment the output is
            A fragment specifier with
                kind = 0
                fontName, fontSize, leading, textColor
                lines=  A list of lines
                        Each line has two items.
                        1) unused width in points
                        2) word list

        B) When there is more than one input formatting fragment the out put is
            A fragment specifier with
                kind = 1
                lines=  A list of fragments each having fields
                            extraspace (needed for justified)
                            fontSize
                            words=word list
                                each word is itself a fragment with
                                various settings

        This structure can be used to easily draw paragraphs with the various alignments.
        You can supply either a single width or a list of widths; the latter will have its
        last item repeated until necessary. A 2-element list is useful when there is a
        different first line indent; a longer list could be created to facilitate custom wraps
        around irregular objects."""

        if type(width) <> ListType: maxWidths = [width]
        else: maxWidths = width
        lines = []
        lineno = 0
        style = self.style
        fFontSize = float(style.fontSize)

        #for bullets, work out width and ensure we wrap the right amount onto line one
        _handleBulletWidth(self.bulletText,style,maxWidths)

        maxWidth = maxWidths[0]

        self.height = 0
        frags = self.frags
        nFrags= len(frags)
        if nFrags==1:
            f = frags[0]
            fontSize = f.fontSize
            fontName = f.fontName
            words = hasattr(f,'text') and split(f.text, ' ') or f.words
            spaceWidth = stringWidth(' ', fontName, fontSize)
            cLine = []
            currentWidth = - spaceWidth   # hack to get around extra space for word 1
            for word in words:
                wordWidth = stringWidth(word, fontName, fontSize)
                newWidth = currentWidth + spaceWidth + wordWidth
                if newWidth<=maxWidth or len(cLine)==0:
                    # fit one more on this line
                    cLine.append(word)
                    currentWidth = newWidth
                else:
                    if currentWidth>self.width: self.width = currentWidth
                    #end of line
                    lines.append((maxWidth - currentWidth, cLine))
                    cLine = [word]
                    currentWidth = wordWidth
                    lineno = lineno + 1
                    try:
                        maxWidth = maxWidths[lineno]
                    except IndexError:
                        maxWidth = maxWidths[-1]  # use the last one

            #deal with any leftovers on the final line
            if cLine!=[]:
                if currentWidth>self.width: self.width = currentWidth
                lines.append((maxWidth - currentWidth, cLine))

            return f.clone(kind=0, lines=lines)
        elif nFrags<=0:
            return ParaLines(kind=0, fontSize=style.fontSize, fontName=style.fontName,
                            textColor=style.textColor, lines=[])
        else:
            if hasattr(self,'blPara'):
                #NB this is an utter hack that awaits the proper information
                #preserving splitting algorithm
                return self.blPara
            n = 0
            nSp = 0
            for w in _getFragWords(frags):
                spaceWidth = stringWidth(' ',w[-1][0].fontName, w[-1][0].fontSize)

                if n==0:
                    currentWidth = -spaceWidth   # hack to get around extra space for word 1
                    words = []
                    maxSize = 0

                wordWidth = w[0]
                f = w[1][0]
                if wordWidth>0:
                    newWidth = currentWidth + spaceWidth + wordWidth
                else:
                    newWidth = currentWidth
                if newWidth<=maxWidth or n==0:
                    # fit one more on this line
                    n = n + 1
                    maxSize = max(maxSize,f.fontSize)
                    nText = w[1][1]
                    if words==[]:
                        g = f.clone()
                        words = [g]
                        g.text = nText
                    elif not _sameFrag(g,f):
                        if currentWidth>0 and ((nText!='' and nText[0]!=' ') or hasattr(f,'cbDefn')):
                            if hasattr(g,'cbDefn'):
                                i = len(words)-1
                                while hasattr(words[i],'cbDefn'): i = i-1
                                words[i].text = words[i].text + ' '
                            else:
                                g.text = g.text + ' '
                            nSp = nSp + 1
                        g = f.clone()
                        words.append(g)
                        g.text = nText
                    else:
                        if nText!='' and nText[0]!=' ':
                            g.text = g.text + ' ' + nText

                    for i in w[2:]:
                        g = i[0].clone()
                        g.text=i[1]
                        words.append(g)
                        maxSize = max(maxSize,g.fontSize)

                    currentWidth = newWidth
                else:
                    if currentWidth>self.width: self.width = currentWidth
                    #end of line
                    lines.append(FragLine(extraSpace=(maxWidth - currentWidth),wordCount=n,
                                        words=words, fontSize=maxSize))

                    #start new line
                    lineno = lineno + 1
                    try:
                        maxWidth = maxWidths[lineno]
                    except IndexError:
                        maxWidth = maxWidths[-1]  # use the last one
                    currentWidth = wordWidth
                    n = 1
                    maxSize = f.fontSize
                    g = f.clone()
                    words = [g]
                    g.text = w[1][1]

                    for i in w[2:]:
                        g = i[0].clone()
                        g.text=i[1]
                        words.append(g)
                        maxSize = max(maxSize,g.fontSize)

            #deal with any leftovers on the final line
            if words<>[]:
                if currentWidth>self.width: self.width = currentWidth
                lines.append(ParaLines(extraSpace=(maxWidth - currentWidth),wordCount=n,
                                    words=words, fontSize=maxSize))
            return ParaLines(kind=1, lines=lines)

        return lines