Example #1
0
    def drawLines(self, lineThickness):
        # Don't do anything if no segments have been selected,
        # or if more than 1 contour has been selected
        if not self.selectedSegments or len(self.selectedContours) > 1:
            return

        contourPoints = self._collectPointsInContour(self.selectedContours[0])

        for segment in self.selectedSegments:
            selectedOnCurves = []
            selectedOffCurves = []
            for point in segment.points:
                if point.type == "offcurve":
                    selectedOffCurves.append(point)
                else:
                    selectedOnCurves.append(point)

            pt0 = self._findPrevOnCurvePt(selectedOnCurves[0],
                                          contourPoints).position
            pt1 = selectedOnCurves[0].position
            pt2 = selectedOffCurves[0].position
            pt3 = selectedOffCurves[1].position

            # if lines are parallel, lines are green; otherwise, red
            if self._checkParallel((pt0, pt1), (pt2, pt3)):
                dt.stroke(0, 1, 0, 1)
            else:
                dt.stroke(1, 0, 0, 1)

            dt.strokeWidth(lineThickness)
            dt.line(pt0, pt1)
            dt.line(pt2, pt3)
    def _handlesPreview(self, info):
        _doodle_glyph = info["glyph"]

        if roboFontVersion > "3.1":
            _doodle_glyph_selected_points = _doodle_glyph.selectedPoints
        else:
            _doodle_glyph_selected_points = _doodle_glyph.selection

        if CurrentGlyph() is not None \
            and _doodle_glyph is not None \
            and len(_doodle_glyph.components) == 0 \
            and _doodle_glyph_selected_points != []:
            glyph = self.tmp_glyph #.copy()
            ref_glyph = CurrentGlyph()
            save()
            stroke(0, 0, 0, 0.3)
            strokeWidth(info["scale"])
            fill(None)
            l = 4 * info["scale"]
            for contourIndex in range(len(glyph)):
                contour = self.tmp_glyph.contours[contourIndex]
                ref_contour = ref_glyph.contours[contourIndex]
                for i in range(len(contour.segments)):
                    segment = contour[i]
                    if ref_contour[i].selected and segment.type == "curve":
                        for p in segment.points[0:2]:
                            x = p.x
                            y = p.y
                            line((x-l, y-l), (x+l, y+l))
                            line((x-l, y+l), (x+l, y-l))
            restore()      
Example #3
0
    def _drawBaseline(self, glyphName):
        glyphToDisplay = self.fontObj[glyphName]

        dt.save()
        dt.stroke(*BLACK)
        dt.fill(None)
        # reversed scaling factor
        dt.strokeWidth(
            1 / (self.ctrlHeight /
                 (self.canvasScalingFactor * self.fontObj.info.unitsPerEm)))
        dt.line((0, 0), (glyphToDisplay.width, 0))
        dt.restore()
    def drawPoints(self, info):
    
        newPoints = self.getValues(None)
        if newPoints != None:
            glyph = CurrentGlyph()
        
            onCurveSize = getDefault("glyphViewOncurvePointsSize") * 5
            offCurveSize = getDefault("glyphViewOncurvePointsSize") * 3
            fillColor = tuple([i for i in getDefault("glyphViewCurvePointsFill")])
        
            upmScale = (glyph.font.info.unitsPerEm/1000) 
            scale = info["scale"]
            oPtSize = onCurveSize * scale
            fPtSize = offCurveSize * scale

            d.save()

            # thanks Erik!
            textLoc = newPoints[0][3][0] + math.cos(self.returnAngle(newPoints)) * (scale*.25*120) * 2, newPoints[0][3][1] + math.sin(self.returnAngle(newPoints)) * (scale*.25*120) * 2

            for b in newPoints:
                for a in b:
                    if a == newPoints[1][0] or a == newPoints[0][-1]:
                        d.oval(a[0]-oPtSize/2,a[1]-oPtSize/2, oPtSize, oPtSize) 
                    else:
                        d.oval(a[0]-fPtSize/2,a[1]-fPtSize/2, fPtSize, fPtSize) 
                    d.fill(fillColor[0],fillColor[1],fillColor[2],fillColor[3])
        
            d.stroke(fillColor[0],fillColor[1],fillColor[2],fillColor[3])
            d.strokeWidth(scale)
            d.line(newPoints[0][2],newPoints[1][1])
            d.restore()

            # https://robofont.com/documentation/building-tools/toolspace/observers/draw-info-text-in-glyph-view/?highlight=draw%20text

            glyphWindow = CurrentGlyphWindow()
            if not glyphWindow:
                return
            glyphView = glyphWindow.getGlyphView()
            textAttributes = {
                AppKit.NSFontAttributeName: AppKit.NSFont.userFixedPitchFontOfSize_(11),
            }
            glyphView.drawTextAtPoint(
            f'{round(abs(math.degrees(self.returnAngle(newPoints)))%180,4)}°\n{str(round(self.returnRatio(newPoints),4))}',
            textAttributes,
            textLoc,
            yOffset=0,
            drawBackground=True,
            centerX=True,
            centerY=True,
            roundBackground=False,)

            UpdateCurrentGlyphView()
Example #5
0
    def _drawGlyphOutline(self, glyph, scalingFactor, offset_X=0):
        dt.save()
        dt.translate(offset_X, 0)

        dt.fill(None)
        dt.strokeWidth(1 * scalingFactor)
        dt.stroke(*LIGHT_GRAY_COLOR)
        dt.drawGlyph(glyph)

        scaledRadius = BCP_RADIUS * scalingFactor

        for eachContour in glyph:
            for eachBPT in eachContour.bPoints:
                dt.stroke(None)
                dt.fill(*LIGHT_GRAY_COLOR)
                dt.rect(eachBPT.anchor[0] - scaledRadius / 2.,
                        eachBPT.anchor[1] - scaledRadius / 2., scaledRadius,
                        scaledRadius)

                if eachBPT.bcpIn != (0, 0):
                    dt.stroke(None)
                    dt.fill(*LIGHT_GRAY_COLOR)
                    dt.oval(
                        eachBPT.anchor[0] + eachBPT.bcpIn[0] -
                        scaledRadius / 2., eachBPT.anchor[1] +
                        eachBPT.bcpIn[1] - scaledRadius / 2., scaledRadius,
                        scaledRadius)

                    dt.stroke(*LIGHT_GRAY_COLOR)
                    dt.fill(None)
                    dt.line((eachBPT.anchor[0], eachBPT.anchor[1]),
                            (eachBPT.anchor[0] + eachBPT.bcpIn[0],
                             eachBPT.anchor[1] + eachBPT.bcpIn[1]))

                if eachBPT.bcpOut != (0, 0):
                    dt.stroke(None)
                    dt.fill(*LIGHT_GRAY_COLOR)
                    dt.oval(
                        eachBPT.anchor[0] + eachBPT.bcpOut[0] -
                        scaledRadius / 2., eachBPT.anchor[1] +
                        eachBPT.bcpOut[1] - scaledRadius / 2., scaledRadius,
                        scaledRadius)

                    dt.stroke(*LIGHT_GRAY_COLOR)
                    dt.fill(None)
                    dt.line((eachBPT.anchor[0], eachBPT.anchor[1]),
                            (eachBPT.anchor[0] + eachBPT.bcpOut[0],
                             eachBPT.anchor[1] + eachBPT.bcpOut[1]))

        dt.restore()
Example #6
0
    def _drawSidebearings(self, glyphName):
        glyphToDisplay = self.fontObj[glyphName]

        dt.save()
        dt.stroke(*BLACK)
        dt.fill(None)

        # reversed scaling factor
        dt.strokeWidth(
            1 / (self.ctrlHeight /
                 (self.canvasScalingFactor * self.fontObj.info.unitsPerEm)))

        dt.fill(*LIGHT_GRAY)
        dt.line(
            (0, self.fontObj.info.descender),
            (0, self.fontObj.info.descender + self.fontObj.info.unitsPerEm))
        dt.line((glyphToDisplay.width, self.fontObj.info.descender),
                (glyphToDisplay.width,
                 self.fontObj.info.descender + self.fontObj.info.unitsPerEm))

        dt.restore()
    def _drawGeometry(self, info):
        reference_glyph = CurrentGlyph()
        #rect(0, 0, 200, 100)
        #rect(0, 0, self.w.eqCurvatureSlider.get() * 200, 100)

        if roboFontVersion > "3.1":
           reference_glyph_selected_points = reference_glyph.selectedPoints
        else:
           reference_glyph_selected_points = reference_glyph.selection
                        
        stroke(0.5, 0.6, 0.9, 0.8)
        strokeWidth(0.8 * info["scale"])
        if reference_glyph_selected_points != []:
            for contourIndex in range(len(reference_glyph.contours)):
                reference_contour = reference_glyph.contours[contourIndex]
                for i in range(len(reference_contour.segments)):
                    reference_segment = reference_contour[i]
                    if reference_segment.selected and reference_segment.type == "curve":
                        # last point of the previous segment
                        p0 = reference_contour[i-1][-1]
                        if len(reference_segment.points) == 3:
                            p1, p2, p3 = reference_segment.points
                            alpha = atan2(p1.y - p0.y, p1.x - p0.x)
                            beta  = atan2(p2.y - p3.y, p2.x - p3.x)
                            if abs(alpha - beta) >= 0.7853981633974483:
                                if isOnLeft(p0, p3, p1) and isOnLeft(p0, p3, p2) or isOnRight(p0, p3, p1) and isOnRight(p0, p3, p2):
                                    
                                    #alpha, beta, gamma = getTriangleAngles(p0, p1, p2, p3)
                                    a, b, c = getTriangleSides(p0, p1, p2, p3)
                                    line((p0.x, p0.y), (p0.x + (c+5) * cos(alpha), p0.y + (c+5) * sin(alpha)))
                                    line((p3.x, p3.y), (p3.x + (a+5) * cos(beta) , p3.y + (a+5) * sin(beta) ))
                                    line((p0.x, p0.y), (p3.x, p3.y))
    def drawBkgnd(self, info):
        # Draw the interpolated glyph outlines
        scale = info["scale"]
        ptSize = 7 * scale
        if self.interpolatedGlyph:
            # Draw the glyph outline
            pen = CocoaPen(None)
            self.interpolatedGlyph.draw(pen)
            dt.fill(r=None, g=None, b=None, a=1)
            dt.stroke(r=0, g=0, b=0, a=0.4)
            dt.strokeWidth(2 * scale)
            dt.save()
            dt.translate(self.currentGlyph.width)
            dt.drawPath(pen.path)
            dt.stroke(r=0, g=0, b=0, a=1)
            # Draw the points and handles
            for contour in self.interpolatedGlyph.contours:
                for bPoint in contour.bPoints:
                    inLoc = self.addPoints(bPoint.anchor, bPoint.bcpIn)
                    outLoc = self.addPoints(bPoint.anchor, bPoint.bcpOut)
                    dt.line(inLoc, bPoint.anchor)
                    dt.line(bPoint.anchor, outLoc)
                    dt.fill(r=1, g=1, b=1, a=1)
                    dt.oval(bPoint.anchor[0] - (ptSize * 0.5),
                            bPoint.anchor[1] - (ptSize * 0.5), ptSize, ptSize)
                    dt.fill(0)
                    # Draw an "X" over each BCP
                    if not bPoint.bcpIn == (0, 0):
                        dt.oval(inLoc[0] - (ptSize * 0.5),
                                inLoc[1] - (ptSize * 0.5), ptSize, ptSize)
                        #dt.line((inLoc[0]-(ptSize*0.5), inLoc[1]-(ptSize*0.5)), (inLoc[0]+(ptSize*0.5), inLoc[1]+(ptSize*0.5)))
                        #dt.line((inLoc[0]+(ptSize*0.5), inLoc[1]-(ptSize*0.5)), (inLoc[0]-(ptSize*0.5), inLoc[1]+(ptSize*0.5)))
                    if not bPoint.bcpOut == (0, 0):
                        dt.oval(outLoc[0] - (ptSize * 0.5),
                                outLoc[1] - (ptSize * 0.5), ptSize, ptSize)
                        #dt.line((outLoc[0]-(ptSize*0.5), outLoc[1]-(ptSize*0.5)), (outLoc[0]+(ptSize*0.5), outLoc[1]+(ptSize*0.5)))
                        #dt.line((outLoc[0]+(ptSize*0.5), outLoc[1]-(ptSize*0.5)), (outLoc[0]-(ptSize*0.5), outLoc[1]+(ptSize*0.5)))

            dt.restore()
Example #9
0
    def draw(self):
        try:
            dt.save()
            dt.font(SYSTEM_FONT_NAME)
            dt.fontSize(CAPTION_BODY_SIZE)
            for indexGlyphName, eachGlyphName in enumerate(
                    self.glyphNamesToDisplay):

                # in this way it does not draw what's outside the canvas frame!
                if SPACING_COL_WIDTH * indexGlyphName > self.getPosSize()[2]:
                    continue

                self._drawMatrixColumn(eachGlyphName)
                dt.translate(SPACING_COL_WIDTH, 0)

                self._setBoxQualities()
                dt.line((0, 0), (0, self.getPosSize()[3]))

            dt.restore()

        except Exception, error:
            print traceback.format_exc()
Example #10
0
    def _drawMetricsData(self, glyphName, offset):
        dt.save()
        glyphToDisplay = self.fontObj[glyphName]
        dt.translate(0, self.fontObj.info.descender)
        reverseScalingFactor = 1 / (
            self.ctrlHeight /
            (self.canvasScalingFactor * self.fontObj.info.unitsPerEm))

        if self.isSidebearingsActive is True:
            dt.fill(None)
            dt.stroke(*BLACK)
            dt.strokeWidth(reverseScalingFactor)
            dt.line((0, 0), (0, -offset * reverseScalingFactor))
            dt.line((glyphToDisplay.width, 0),
                    (glyphToDisplay.width, -offset * reverseScalingFactor))
        dt.restore()

        dt.save()
        dt.translate(0, self.fontObj.info.descender)
        dt.translate(0, -offset * reverseScalingFactor)
        dt.fill(*BLACK)

        dt.stroke(None)
        dt.font(SYSTEM_FONT_NAME)
        dt.fontSize(BODY_SIZE * reverseScalingFactor)

        textWidth, textHeight = dt.textSize(u'{}'.format(glyphToDisplay.width))
        dt.textBox(u'{:d}'.format(int(glyphToDisplay.width)),
                   (0, 0, glyphToDisplay.width, textHeight * 2),
                   align='center')
        dt.textBox(u'\n{:d}'.format(int(glyphToDisplay.leftMargin)),
                   (0, 0, glyphToDisplay.width / 2., textHeight * 2),
                   align='center')
        dt.textBox(u'\n{:d}'.format(int(glyphToDisplay.rightMargin)),
                   (glyphToDisplay.width / 2., 0, glyphToDisplay.width / 2.,
                    textHeight * 2),
                   align='center')
        dt.restore()
Example #11
0
    def _drawDiagonals(self, currentGlyph, scalingFactor, offset_X=0):
        if DIAGONALS_KEY not in currentGlyph.lib:
            return None

        diagonalsData = calcDiagonalsData(currentGlyph, DIAGONALS_KEY)
        for ptsToDisplay, angle, distance in diagonalsData:
            pt1, pt2 = ptsToDisplay

            dt.save()
            dt.stroke(*self.diagonalColor)
            dt.fill(None)
            dt.strokeWidth(1 * scalingFactor)

            if 90 < angle <= 180 or -180 < angle < -90:
                direction = -1
                adjustedAngle = angle + 180 + 90
            else:
                direction = 1
                adjustedAngle = angle + 90

            diagonalPt1 = pt1[0] + cos(radians(adjustedAngle)) * (
                (DIAGONAL_OFFSET - 1) * direction), pt1[1] + sin(
                    radians(adjustedAngle)) * (
                        (DIAGONAL_OFFSET - 1) * direction)
            diagonalPt2 = pt2[0] + cos(radians(adjustedAngle)) * (
                (DIAGONAL_OFFSET - 1) * direction), pt2[1] + sin(
                    radians(adjustedAngle)) * (
                        (DIAGONAL_OFFSET - 1) * direction)
            offsetPt1 = pt1[0] + cos(radians(
                adjustedAngle)) * DIAGONAL_OFFSET * direction, pt1[1] + sin(
                    radians(adjustedAngle)) * DIAGONAL_OFFSET * direction
            offsetPt2 = pt2[0] + cos(radians(
                adjustedAngle)) * DIAGONAL_OFFSET * direction, pt2[1] + sin(
                    radians(adjustedAngle)) * DIAGONAL_OFFSET * direction

            dt.line((pt1), (offsetPt1))
            dt.line((pt2), (offsetPt2))
            dt.line((diagonalPt1), (diagonalPt2))
            dt.restore()

            dt.save()
            textQualities(BODYSIZE_CAPTION * scalingFactor)
            offsetMidPoint = calcMidPoint(offsetPt1, offsetPt2)
            dt.translate(offsetMidPoint[0], offsetMidPoint[1])

            if 90 < angle <= 180 or -180 < angle < -90:
                dt.rotate(angle + 180)
                textBoxY = -BODYSIZE_CAPTION * 1.2 * scalingFactor
            else:
                dt.rotate(angle)
                textBoxY = 0

            dataToPlot = u'∡{:.1f} ↗{:d}'.format(angle % 180, int(distance))
            textWidth, textHeight = dt.textSize(dataToPlot)
            dt.textBox(dataToPlot, (-textWidth / 2., textBoxY, textWidth,
                                    BODYSIZE_CAPTION * 1.2 * scalingFactor),
                       align='center')
            dt.restore()
    def draw(self, infoOrScale, glyph=None, lineWeightMultiplier=1):
        """
        Draw lines.

        This method is called by both the observer watching
        "draw" (turned on when "/" is pressed) and by the tool,
        when it's active.

        When used by the observer, it returns "info", a dict
        from which we need to grab scale. When used by the tool,
        it returns scale, so we can use it right away.
        """
        # This is just for naming...
        self.scale = infoOrScale
        if isinstance(infoOrScale, dict) and glyph is None:
            self.scale = infoOrScale["scale"]
            glyph = infoOrScale["glyph"]

        # Just in case...
        if self.scale is None or glyph is None:
            return

        # Also do this here in case mouseDown isn't fired
        # (eg. user uses keyboard to select segments)
        self._analyzeSelection(glyph)

        for selected in self._selectedSegments:
            p1, segment = selected
            h1, h2, p2 = segment
            if hf.areTheyParallel((p1, p2,), (h1, h2), self.tolerance):
                dt.stroke(0, 0, 1, 1)
            else:
                dt.stroke(1, 0, 0, 1)
            dt.strokeWidth(self.scale)
            dt.line((p1.x, p1.y), (p2.x, p2.y))
            dt.strokeWidth(self.scale * lineWeightMultiplier)
            dt.line((h1.x, h1.y), (h2.x, h2.y))
Example #13
0
 def draw_histogram(self, font, upm, color, show_glyphs=False, histogram=None):
     if histogram is None:
         if self.histogram is None:
             return
         histogram = self.histogram
     drawing.save()
     drawing.fill(1, 0.5, 0.2, 1.0)
     drawing.stroke(color[0], color[1], color[2], color[3])
     for width in sorted(histogram.keys()):
         num = len(histogram[width])
         x = 10 + width * self.histogram_width / (upm * self.ems_horizontal)
         drawing.save()
         if show_glyphs:
             drawing.save()
             drawing.fill(color[0], color[1], color[2], 0.2)
             drawing.fontsize(self.scale_vertical)
             for i in range(len(histogram[width])):
                 glyph_name = histogram[width][i]
                 if glyph_name in font:
                     u = font[glyph_name].unicode
                     if u:
                         drawing.text("%s" % unichr(u), x + 4, 18 + i * self.scale_vertical)
                     else:
                         drawing.text("%s" % glyph_name, x + 4, 18 + i * self.scale_vertical)
                 else:
                     drawing.text("%s" % glyph_name, x + 4, 18 + i * self.scale_vertical)
             drawing.restore()
             drawing.strokewidth(2)
         else:
             drawing.strokewidth(6)
         # draw bars
         drawing.line(x, 20, x, 20 + num * self.scale_vertical)
         drawing.strokewidth(0)
         drawing.text("%s" % (num), x - 3 * len(str(num)), 22 + num * self.scale_vertical)
         drawing.restore()
     drawing.restore()
Example #14
0
    def draw(self):
        self.graph_in_window = []
        c_width, c_height = self.parent.graph_width, self.parent.graph_height

        drawBot.fill(None)

        # horizontal line
        drawBot.stroke(0)
        drawBot.strokeWidth(0.5)
        drawBot.line((0, c_height / 2), (c_width, c_height / 2))

        # vertical lines
        # the combination of both margins equal one additional step
        graph_margin = self.parent.step_dist / 2
        for i in range(self.parent.steps + 1):
            x = graph_margin + i * self.parent.step_dist
            drawBot.line((x, 0), (x, c_height))

        # the graph
        drawBot.stroke(0, 0, 1)
        drawBot.strokeWidth(5)
        drawBot.lineCap('round')

        prev = None
        max_value = max([abs(v) for v in self.parent.number_values])
        zero_point = c_height / 2
        min_scale = 40
        self.max_allowed_value = 500
        self.graph_scale = max_value / self.parent.graph_height
        self.min_graph_scale = min_scale / self.parent.graph_height
        slider_controls = []

        for i, value in enumerate(self.parent.number_values):
            if max_value > min_scale:
                self.amplitude = value / max_value
            else:
                self.amplitude = value / min_scale

            x = graph_margin + i * self.parent.step_dist
            y = zero_point + c_height * 0.4 * self.amplitude
            y_window = (self.parent.w_height - self.parent.graph_height + y -
                        self.parent.padding)
            self.graph_in_window.append((x, y_window))
            if prev:
                drawBot.line(prev, (x, y))
            prev = x, y
            slider_controls.append((x, y))

        # slider heads
        for x, y in slider_controls:
            radius = 10
            drawBot.fill(1)
            drawBot.stroke(0)
            drawBot.strokeWidth(0.5)
            drawBot.oval(x - radius, y - radius, 2 * radius, 2 * radius)
Example #15
0
 def _drawArrow(self, position, kind, size, width):
     x, y = position
     save()
     translate(x, y)
     fill(0, 0.8, 0, 0.1)
     strokeWidth(width)
     stroke(0.9, 0.1, 0, 0.85)
     line(-width/2, 0, size, 0)
     line(0, width/2, 0, -size)
     line(0, 0, size, -size)
     #rect(x-scale, y-scale, scale, scale)
     if self.showLabels:
         fill(0.4, 0.4, 0.4, 0.7)
         stroke(None)
         font("LucidaGrande")
         fontSize(int(round(size * 1.1)))
         text(kind, (int(round(size * 1.8)), int(round(-size))))
     restore()
Example #16
0
 def _drawArrow(self, position, kind, size, width):
     x, y = position
     save()
     translate(x, y)
     fill(0, 0.8, 0, 0.1)
     strokeWidth(width)
     stroke(0.9, 0.1, 0, 0.85)
     line(-width / 2, 0, size, 0)
     line(0, width / 2, 0, -size)
     line(0, 0, size, -size)
     #rect(x-scale, y-scale, scale, scale)
     if self.showLabels:
         fill(0.4, 0.4, 0.4, 0.7)
         stroke(None)
         font("LucidaGrande")
         fontSize(int(round(size * 1.1)))
         text(kind, (int(round(size * 1.8)), int(round(-size))))
     restore()
Example #17
0
 def _drawGlyphCellArrow(self, num_errors):
     x = 3
     y = 3
     width = 2
     size = 7
     save()
     translate(4, 4)
     
     fill(0.9, 0.4, 0.3, 1)
     rect(-1, -1, size+1, size+1)
     
     lineJoin("round")
     lineCap("butt") # butt, square, round
     strokeWidth(width)
     stroke(1, 1, 1)
     line(-width/2, 0, size, 0)
     line(0, -width/2, 0, size)
     line(width/2, width/2, size-0.5, size-0.5)
     
     restore()
Example #18
0
 def _drawGrid(self):
     label_every = 1
     if self.units > 24:
         label_every = 2
     drawing.save()
     drawing.strokeWidth(0)
     drawing.stroke(None)
     drawing.fill(0.88, 0.92, 0.98)
     if self.system is not None:
         if self.system.min_units is not None:
             drawing.rect(0, 0, 10 + self.system.min_units * self.histogram_width / (self.units * self.ems_horizontal), self.histogram_height)
         if self.system.max_units is not None:
             drawing.rect(10 + self.system.max_units * self.histogram_width / (self.units * self.ems_horizontal), 0, self.histogram_width, self.histogram_height)
     
     drawing.strokeWidth(1.0)
     drawing.stroke(0.8, 0.8, 0.8)
     drawing.fill(0.6, 0.6, 0.6)
     for u in range(0, int(ceil(self.units * self.ems_horizontal))):
         x = 10 + u * self.histogram_width / (self.units * self.ems_horizontal)
         if u == self.units:
             # mark the full em
             drawing.stroke(0, 0, 0)
             drawing.line(x, 20, x, self.histogram_height-10)
             drawing.strokeWidth(0)
             drawing.text("1 em", x + 4, self.histogram_height - 21)
             drawing.strokeWidth(1.0)
         elif u % 10 == 0:
             # make every 10th line darker
             drawing.stroke(0.5, 0.5, 0.5)
             drawing.line(x, 20, x, self.histogram_height - 20)
         else:
             drawing.stroke(0.8, 0.8, 0.8)
             drawing.line(x, 20, x, self.histogram_height - 30)
         if u % label_every == 0:
             drawing.strokeWidth(0)
             drawing.text("%s" % (u), x - 3 * len(str(u)), 5)
     drawing.restore()
Example #19
0
    def _drawGlyphCellArrow(self, num_errors):
        x = 3
        y = 3
        width = 2
        size = 7
        save()
        translate(4, 4)

        stroke(0.2)
        strokeWidth(0.5)
        lineJoin("miter")
        fill(0.9, 0.4, 0.3)
        rect(-1, -1, size + 1, size + 1)

        lineCap("butt")  # butt, square, round
        strokeWidth(width)
        stroke(1, 0.9, 0.65)
        line((0, width / 2 - 0.5), (size - width / 2 + 0.5, width / 2 - 0.5))
        line((width / 2 - 0.5, width / 2 - 1.5),
             (width / 2 - 0.5, size - width / 2 + 0.5))
        lineCap("round")
        line((width // 2, width // 2), (size - 1.5, size - 1.5))

        restore()
Example #20
0
    def _drawMatrixColumn(self, glyphName):
        dt.save()

        # definitive
        dt.translate(
            0,
            self.getPosSize()[3] - vanillaControlsSize['EditTextSmallHeight'])

        # top
        dt.fill(*BLACK)
        dt.stroke(None)

        textWidth, textHeight = dt.textSize(glyphName)
        self._setTypeQualities(BLACK)
        dt.text(glyphName,
                (SPACING_COL_WIDTH / 2. - textWidth / 2., BASELINE_CORRECTION))
        dt.translate(0, -vanillaControlsSize['EditTextSmallHeight'])

        # metrics
        for eachFont in self.fontsOrder:
            try:
                eachGlyph = eachFont[glyphName]
            except Exception, error:
                continue

            if eachGlyph == self.lineViewSelectedGlyph:
                color = RED
            else:
                color = BLACK

            # line over glyph width
            self._setBoxQualities()
            dt.line((0, vanillaControlsSize['EditTextSmallHeight']),
                    (SPACING_COL_WIDTH,
                     vanillaControlsSize['EditTextSmallHeight']))

            widthString = '{:d}'.format(int(round(eachGlyph.width, 0)))
            textWidth, textHeight = dt.textSize(widthString)
            self._setTypeQualities(color)
            dt.text(
                widthString,
                (SPACING_COL_WIDTH / 2. - textWidth / 2., BASELINE_CORRECTION))

            # line over sidebearings
            self._setBoxQualities()
            dt.line((0, 0), (SPACING_COL_WIDTH, 0))
            dt.translate(0, -vanillaControlsSize['EditTextSmallHeight'])

            leftMarginString = '{:d}'.format(
                int(round(eachGlyph.leftMargin, 0)))
            textWidth, textHeight = dt.textSize(leftMarginString)
            self._setTypeQualities(color)
            dt.text(
                leftMarginString,
                (SPACING_COL_WIDTH / 4. - textWidth / 2., BASELINE_CORRECTION))

            self._setBoxQualities()
            dt.line((SPACING_COL_WIDTH / 2., 0),
                    (SPACING_COL_WIDTH / 2.,
                     vanillaControlsSize['EditTextSmallHeight']))

            rightMarginString = '{:d}'.format(
                int(round(eachGlyph.rightMargin, 0)))
            textWidth, textHeight = dt.textSize(rightMarginString)
            self._setTypeQualities(color)
            dt.text(rightMarginString,
                    (SPACING_COL_WIDTH * 3 / 4. - textWidth / 2.,
                     BASELINE_CORRECTION))

            dt.translate(0, -vanillaControlsSize['EditTextSmallHeight'])
    def draw(self):
        w = self.w.c.width()
        h = self.w.c.height()
        m = 130
        center = w * .5, h * .5
        d = self.dotSize
        r = min(.5 * (h - 2 * m), .5 * (w - 2 * m))
        if self.pointer is None:
            self.pointer = center

        a1 = self.orientation * math.pi
        a2 = a1 + 2 / 3 * math.pi
        a3 = a1 - 2 / 3 * math.pi
        self.p1 = p1 = center[0] + (r * math.sin(a1)), center[1] + (
            r * math.cos(a1))
        self.p2 = p2 = center[0] + (r * math.sin(a2)), center[1] + (
            r * math.cos(a2))
        self.p3 = p3 = center[0] + (r * math.sin(a3)), center[1] + (
            r * math.cos(a3))

        self.snapped = None
        if self.closeToPoint(self.p1, self.pointer):
            self.pointer = self.p1
            self.snapped = 0
        if self.closeToPoint(self.p2, self.pointer):
            self.pointer = self.p2
            self.snapped = 1
        if self.closeToPoint(self.p3, self.pointer):
            self.pointer = self.p3
            self.snapped = 2

        p1d = p1[0] - .5 * d, p1[1] - .5 * d, d, d
        p2d = p2[0] - .5 * d, p2[1] - .5 * d, d, d
        p3d = p3[0] - .5 * d, p3[1] - .5 * d, d, d

        ctx.save()
        ctx.stroke(.8, .8, .7)
        ctx.strokeWidth(.4)
        ctx.strokeWidth(.8)
        ctx.line(p1, p2)
        ctx.line(p2, p3)
        ctx.line(p3, p1)

        if self.pointer is not None:
            ctx.line(p1, self.pointer)
            ctx.line(p2, self.pointer)
            ctx.line(p3, self.pointer)

        ctx.stroke(None)
        ctx.fill(0)
        ctx.oval(*p1d)
        ctx.oval(*p2d)
        ctx.oval(*p3d)

        g1, g2, g3 = self.glyphs
        if g1 is not None:
            ctx.save()
            ctx.translate(p1[0], p1[1])
            ctx.scale(self.glyphScale)
            ctx.translate(100, 0)
            ctx.drawGlyph(g1)
            ctx.restore()
        if g2 is not None:
            ctx.save()
            ctx.translate(p2[0], p2[1])
            ctx.scale(self.glyphScale)
            ctx.translate(100, 0)
            ctx.drawGlyph(g2)
            ctx.restore()
        if g3 is not None:
            ctx.save()
            ctx.translate(p3[0], p3[1])
            ctx.scale(self.glyphScale)
            ctx.translate(100, 0)
            ctx.drawGlyph(g3)
            ctx.restore()

        if self.pointer:
            ctx.save()
            ctx.fill(1, 0, 0)
            ctx.stroke(None)
            d = 10
            ctx.oval(self.pointer[0] - .5 * d, self.pointer[1] - .5 * d, d, d)

            f1, f2, f3 = ip(p1, p2, p3, self.pointer)
            self._factors = f1, f2, f3
            r = None
            if self.mGlyphs is not None:
                if None not in self.mGlyphs:
                    try:
                        self.result = r = f1 * self.mGlyphs[
                            0] + f2 * self.mGlyphs[1] + f3 * self.mGlyphs[2]
                    except IndexError or TypeError:
                        print("Sorry, these glyphs can't interpolate..")
                    if r:
                        ctx.save()
                        ctx.translate(self.pointer[0], self.pointer[1])
                        ctx.scale(self.glyphScale)
                        ctx.translate(100, 0)
                        g = RGlyph()
                        g.fromMathGlyph(r)
                        ctx.drawGlyph(g)

                        t = "{:02.2f}, {:02.2f}, {:02.2f}".format(f1, f2, f3)
                        ctx.font("Menlo-Regular")
                        ctx.fontSize(6 / self.glyphScale)
                        ctx.text(t, (0, -200))
                        ctx.restore()
            ctx.restore()
        ctx.restore()
Example #22
0
 def _canvas_draw_metrics(self):
     save()
     strokeWidth(1 / self.scale)
     stroke(0.8, 0.8, 0.8)
     line((0, 0), (self.width, 0))
     line((0, self.metrics[0]), (self.width, self.metrics[0]))
     line((0, self.metrics[1]), (self.width, self.metrics[1]))
     line((0, self.metrics[2]), (self.width, self.metrics[2]))
     line((0, self.metrics[3]), (self.width, self.metrics[3]))
     line((0, self.metrics[3]), (0, self.metrics[0]))
     line((self.width, self.metrics[3]), (self.width, self.metrics[0]))
     restore()
Example #23
0
    def drawAxisPreview(self,
                        glyph,
                        color,
                        scale,
                        customColor,
                        view=False,
                        flatComponentColor=(.8, .6, 0, .7),
                        drawSelectedElements=True):
        mjdt.save()
        index = None
        # loc = {}
        # if glyph.selectedSourceAxis:
        #     loc = {glyph.selectedSourceAxis:1}
        # for i, atomicInstance in enumerate(glyph.preview()):
        for i, atomicInstance in enumerate(
                glyph.preview(forceRefresh=False, axisPreview=True)):
            # for i, atomicInstance in enumerate(glyph.previewGlyph):
            transformIntance = atomicInstance._transformation
            atomicInstance = atomicInstance.glyph

            mjdt.fill(*color)
            if drawSelectedElements and i in glyph.selectedElement:
                mjdt.save()
                mjdt.stroke(1, 0, 0, 1)
                mjdt.strokeWidth(1 * scale)
                tx = transformIntance['x'] + transformIntance['tcenterx']
                ty = transformIntance['y'] + transformIntance['tcentery']
                mjdt.line((tx - 5 * scale, ty), (tx + 5 * scale, ty))
                mjdt.line((tx, ty - 5 * scale), (tx, ty + 5 * scale))
                mjdt.stroke(None)
                mjdt.fill(1, 0, 0, 1)
                mjdt.fontSize(8 * scale)
                mjdt.textBox(
                    f"{int(transformIntance['tcenterx'])} {int(transformIntance['tcentery'])}",
                    ((tx - 30 * scale, ty - 30 * scale, 60 * scale,
                      20 * scale)),
                    align="center")
                mjdt.restore()
                mjdt.fill(0, .8, .8, .5)

            # for c in atomicInstance:
            #     if c.clockwise:
            #         mjdt.stroke(1, 0, 0, 1)
            #         mjdt.strokeWidth(2*scale)
            mjdt.save()
            # mjdt.drawGlyph(atomicInstance.getTransformedGlyph(round = self.RCJKI.roundToGrid))
            mjdt.drawGlyph(atomicInstance)
            mjdt.restore()
            if customColor is None and view:
                if i != index:
                    self.drawIndexOfElements(i, atomicInstance, view)
                    if glyph.type == "characterGlyph":
                        response = self.RCJKI.currentFont.mysqlGlyphData.get(
                            glyph.name, False)
                        try:
                            if response:
                                for dc in response["made_of"]:
                                    if dc["name"] != glyph._deepComponents[
                                            i].name:
                                        continue
                                    char = getChar(dc["name"])
                                    if not char: continue
                                    txt = "%s/%s\nused at %s%s" % (
                                        len(dc["used_by"]),
                                        len(self.RCJKI.currentFont.
                                            deepComponents2Chars[char]),
                                        round(
                                            (len(dc["used_by"]) /
                                             len(self.RCJKI.currentFont.
                                                 deepComponents2Chars[char])) *
                                            100), "%")
                                    x, y = atomicInstance[0].points[
                                        0].x, atomicInstance[0].points[0].y
                                    mjdt.fill(1, 0, 1, 1)
                                    mjdt.fontSize(10 * scale)
                                    mjdt.text(txt, (x, y - 30 * scale))
                        except Exception as e:
                            pass
            index = i
        if customColor is None:
            mjdt.fill(customColor)
        else:
            mjdt.fill(*customColor)

        mjdt.drawGlyph(glyph)
        mjdt.restore()

        for c in glyph.flatComponents:
            if self.RCJKI.currentFont[c.baseGlyph].type == "atomicElement":
                mjdt.drawGlyph(
                    self.roundGlyph(self.RCJKI.currentFont[c.baseGlyph]))
            else:
                # self.RCJKI.currentFont[c.baseGlyph].preview.computeDeepComponents(update = False)
                self.drawAxisPreview(self.RCJKI.currentFont[c.baseGlyph],
                                     flatComponentColor, scale, customColor,
                                     view)
Example #24
0
    def _drawGrids(self, frameOrigin, frameSize, italicAngle, scalingFactor):
        if not italicAngle:
            italicAngle = 0

        for eachGridDescription in reversed(self.gridsDB):
            gridColor = eachGridDescription['color']
            isHorizontal = eachGridDescription['horizontal']
            isVertical = eachGridDescription['vertical']
            gridStep = eachGridDescription['step']

            if isHorizontal is False and isVertical is False:
                continue
            if not gridStep:
                continue

            dt.save()
            dt.skew(-italicAngle, 0)
            dt.stroke(*gridColor)
            dt.strokeWidth(.5 * scalingFactor)
            dt.fill(None)

            if isVertical is True:
                # to the right (from 0)
                extraSlant = int(
                    ceil(tan(radians(italicAngle)) * frameOrigin[1]))
                for eachX in range(0,
                                   frameOrigin[0] + frameSize[0] + extraSlant,
                                   gridStep):
                    dt.line((eachX, frameOrigin[1] - GRID_TOLERANCE),
                            (eachX,
                             frameOrigin[1] + frameSize[1] + GRID_TOLERANCE))

                # to the left (from 0)
                extraSlant = int(
                    ceil(
                        tan(radians(italicAngle)) *
                        (frameSize[1] + frameOrigin[1])))
                for eachX in [
                        i for i in range(frameOrigin[0] + extraSlant, 0)
                        if i % gridStep == 0
                ]:
                    dt.line((eachX, frameOrigin[1] - GRID_TOLERANCE),
                            (eachX,
                             frameOrigin[1] + frameSize[1] + GRID_TOLERANCE))

            if isHorizontal is True:
                # to the top (from baseline)
                for eachY in range(0, frameOrigin[1] + frameSize[1], gridStep):
                    dt.line((frameOrigin[0] - GRID_TOLERANCE, eachY),
                            (frameOrigin[0] + frameSize[0] + GRID_TOLERANCE,
                             eachY))

                # to the bottom (from baseline)
                for eachY in [
                        i for i in range(frameOrigin[1], 0)
                        if i % gridStep == 0
                ]:
                    dt.line((frameOrigin[0] - GRID_TOLERANCE, eachY),
                            (frameOrigin[0] + frameSize[0] + GRID_TOLERANCE,
                             eachY))

            dt.restore()