Next / Previous / Contents / Shipman's homepage

19.3. BodyLayout.__findWidths(): Calculate width-related dimensions

listext2
# - - -   B o d y L a y o u t . _ _ f i n d W i d t h s

    def __findWidths(self):
        '''Determine variable width dimensions.

          [ self.pageBox and self.oddMargins are as invariants ->
              self.oneColWide  :=  as invariant
              self.oneCharWide  :=  as invariant
              self.charsPerCol  :=  as invariant ]
        '''

To compute the number of characters per column, first we need to compute the width of a column. If there are N columns, there are N-1 column gaps; the remaining space is divided equally among the columns. The constants Section 8.21, “HAIRLINE_WIDE and Section 8.22, “LEFT_RULE_PAD account for the left-side rule and the padding inside it.

listext2
        #-- 1
        # [ allColsWide  :=  width of the page minus both side margins
        #   sumOfGaps  :=  width of (self.nCols-1) gaps ]
        allColsWide = (self.oddDims.pageBox.wide -
            (self.oddDims.pageMargins.left +
             self.oddDims.pageMargins.right))
        sumOfGaps = COL_GAP * (Args().nCols-1)

        #-- 2
        # [ fullColWide  :=  width of each column including its
        #       hairline left rule and left padding
        #   self.oneColWide  :=  width of each column not including
        #       its rule and padding, as an h.FoDim
        #   oneColPoints  :=  width of each column not including its
        #       rule and padding, as an h.FoDim in points ]
        fullColWide = (allColsWide - sumOfGaps) / (Args().nCols)
        self.oneColWide = fullColWide - HAIRLINE_WIDE - LEFT_RULE_PAD
        oneColPoints = self.oneColWide.convert('pt')

Now that we know how wide a column is, we can compute the number of characters per column. First we need the width of one character, which is obtained by dividing the point size by the aspect ratio: for example, if the aspect ratio is 5/3, a character in a 10-point font would be 6 points wide.

listext2
        #-- 3
        # [ self.oneCharWide  :=  the width of one character of size
        #       (pointSize) with aspect ratio (fontAspect), in points,
        #       as an h.FoDim ]
        self.oneCharWide = h.FoDim(Decimal(Args().pointSize) /
                                   FONT_ASPECT, "pt")

        #-- 4
        self.charsPerCol = int(oneColPoints.n/self.oneCharWide.n)

Next we set up the indentation for overflow lines. The constant Section 8.25, “OVERFLOW_INDENT is given in characters. However, if the column is narrower than this value, we fall back to half a column width, but never less than 1.

listext2
        #-- 5
        # [ self.charsPerOver  :=  capacity of an overflow line in
        #       characters, but never less than 1
        #   self.indent  :=  amount to indent an overflow line as an
        #       h.FoDim, but never less than one character ]
        self.charsPerOver = self.charsPerCol - OVERFLOW_INDENT
        if self.charsPerOver <= 0:
            self.charsPerOver = max(1, self.charsPerCol/2)
        self.indent = self.oneCharWide *(self.charsPerCol -
                                         self.charsPerOver)