Draw arced lines over the text

@access private
3000
function arcLines()
  {
    $colors = explode(',', $this->arc_line_colors);
    imagesetthickness($this->im, 3);

    $color = $colors[rand(0, sizeof($colors) - 1)];
    $linecolor = imagecolorallocate($this->im, hexdec(substr($color, 1, 2)), hexdec(substr($color, 3, 2)), hexdec(substr($color, 5, 2)));

    $xpos   = $this->text_x_start + ($this->font_size * 2) + rand(-5, 5);
    $width  = $this->image_width / 2.66 + rand(3, 10);
    $height = $this->font_size * 2.14 - rand(3, 10);

    if ( rand(0,100) % 2 == 0 ) {
      $start = rand(0,66);
      $ypos  = $this->image_height / 2 - rand(5, 15);
      $xpos += rand(5, 15);
    } else {
      $start = rand(180, 246);
      $ypos  = $this->image_height / 2 + rand(5, 15);
    }

    $end = $start + rand(75, 110);

    imagearc($this->im, $xpos, $ypos, $width, $height, $start, $end, $linecolor);

    $color = $colors[rand(0, sizeof($colors) - 1)];
    $linecolor = imagecolorallocate($this->im, hexdec(substr($color, 1, 2)), hexdec(substr($color, 3, 2)), hexdec(substr($color, 5, 2)));

    if ( rand(1,75) % 2 == 0 ) {
      $start = rand(45, 111);
      $ypos  = $this->image_height / 2 - rand(5, 15);
      $xpos += rand(5, 15);
    } else {
      $start = rand(200, 250);
      $ypos  = $this->image_height / 2 + rand(5, 15);
    }

    $end = $start + rand(75, 100);

    imagearc($this->im, $this->image_width * .75, $ypos, $width, $height, $start, $end, $linecolor);
  }
108841
function text($x, $y, $text, $font, $size, $color = array(0, 0, 0), $adjust = 0.0, $char_space = 0.0, $angle = 0.0) { //***
		//Helpers::dompdf_debug("trace", "($x, $y, $text, ". basename($font) .", $size, [$color[0], $color[1], $color[2]], $adjust, $angle, $blend, $opacity)");

		list ($r, $g, $b) = $this->_get_rgb($color);
		$this->_pdf->SetTextColor($r, $g, $b);
		//***$this->_set_line_transparency($blend, $opacity);
		//***$this->_set_fill_transparency($blend, $opacity);

		$fontdata = $this->_get_font($font);
		$this->_pdf->SetFont($fontdata['family'], $fontdata['style'] /*strpos($font, '-Bold') === false ? '' : 'B'*/, $size, $font);

		//$this->_pdf->SetFontSize($size); // ???

		if ($adjust > 0) {
			$a = explode(' ', $text);
			//$this->_pdf->SetXY($x - 3, $y + (self::FONT_HEIGHT_SCALE - 1) * $size);
			$this->_pdf->SetXY($x, $y);

			//$y += self::FONT_HEIGHT_SCALE * $size + 1;
			for ($i = 0; $i < count($a)-1; $i++) {
				$this->_pdf->Write($size, $a[$i].' ', '');
				//$this->_pdf->Text($x, $y, $a[$i].' ');
				$this->_pdf->SetX($this->_pdf->GetX()+$adjust);
				//$x += $this->_pdf->GetX() + $adjust;
			}
			$this->_pdf->Write($size, $a[$i], '');
			//$this->_pdf->Text($x, $y, $a[$i].' ');
		}
		else {
			if ($angle != 0) {
				$this->_pdf->StartTransform();
				//$y += self::FONT_HEIGHT_SCALE * $size;
				//$y += $size;
				$this->_pdf->Rotate(-$angle, $x, $y);
				$this->_pdf->Text($x, $y, $text, false, false, true, 0, 0, '', 0, '', 0, false, 'T', 'T');
				$this->_pdf->StopTransform();
			}
			else {
				//$pippo = $this->_pdf->getFontAscent($fontdata['family'], $fontdata['style'], $size);
				//$y += $pippo / 8;
				//$y = $y - 0.85 * $size;	// + 0.8 * $size;
				$this->_pdf->Text($x, $y, $text, false, false, true, 0, 0, '', 0, '', 0, false, 'T', 'T');
			}
		}
	}
785603
function DrawBars() {

    if ($this->data_type != "text-data") {
      $this->DrawError('Bar plots must be text-data: use function SetDataType("text-data")');
    }

    $xadjust = ($this->records_per_group * $this->record_bar_width )/4;

    reset($this->data_values);
    while (list($j, $row) = each($this->data_values)) {

      $color_index = 0;
      $colbarcount = 0;
      $x_now = $this->xtr($j+.5);

      while (list($k, $v) = each($row)) {
        if ($k == 0) {
          //Draw Data Labels
          $xlab = SubStr($v,0,$this->x_datalabel_maxlength);
          $this->DrawXDataLabel($xlab,$x_now);
        } else {
          // Draw Bars ($v)
          $x1 = $x_now - $this->data_group_space + ($k-1)*$this->record_bar_width;
          $x2 = $x1 + $this->record_bar_width*$this->bar_width_adjust;

          if ($v < $this->x_axis_position) {
            $y1 = $this->ytr($this->x_axis_position);
            $y2 = $this->ytr($v);
          } else {
            $y1 = $this->ytr($v);
            $y2 = $this->ytr($this->x_axis_position);
          }

          if ($color_index >= count($this->ndx_data_color)) $color_index=0;
          if ($colbarcount >= count($this->ndx_data_border_color)) $colbarcount=0;
          $barcol = $this->ndx_data_color[$color_index];
          $bordercol = $this->ndx_data_border_color[$colbarcount];

          if ((strval($v) != "") ) {   //Allow for missing Y data
            if ($this->shading > 0) {
              for($i=0;$i<($this->shading);$i++) {
              //Shading set in SetDefaultColors
              ImageFilledRectangle($this->img, $x1+$i, $y1-$i, $x2+$i, $y2-$i, $this->ndx_i_light);
              }
            }

            ImageFilledRectangle($this->img, $x1, $y1, $x2, $y2, $barcol);
            ImageRectangle($this->img, $x1, $y1, $x2, $y2, $bordercol);
            if ($this->draw_data_labels == '1') {  //ajo
              $y1 = $this->ytr($this->label_scale_position * $v);
              //$this->DrawDataLabel($v,$j + .5,$v*$this->label_scale_position);
              $this->DrawText($this->small_font, $this->x_label_angle,
                $x1+$this->record_bar_width/2, $y1, $this->ndx_label_color, $this->x_label_ttffont_size, $v,'center','top');
            }
          }

          $color_index++;
          $colbarcount++;
        }
      }
    }
  }
1256159
function drawHorizontalGridLines() {
            maskGridLines = svg.select('.grid-lines-group')
                .selectAll('line.vertical-grid-line')
                .data(xScale.ticks(xTicks).slice(1))
                .enter()
                  .append('line')
                    .attr('class', 'vertical-grid-line')
                    .attr('y1', (xAxisPadding.left))
                    .attr('y2', chartHeight)
                    .attr('x1', (d) => xScale(d))
                    .attr('x2', (d) => xScale(d))

            drawVerticalExtendedLine();
        }
667042
function() {
      this.ctx = this.canvas.getContext("2d");
      this.ctx.strokeStyle = this.settings.lineColor;
      this.ctx.lineWidth = this.settings.lineWidth;
    }
900199
function drawLines(){
            let lines,
                topicLine;

            topicLine = d3Shape.line()
                .curve(curveMap[lineCurve])
                .x(({date}) => xScale(date))
                .y(({value}) => yScale(value));

            lines = svg.select('.chart-group').selectAll('.line')
                .data(dataByTopic, getTopic);

            paths = lines.enter()
              .append('g')
                .attr('class', 'topic')
              .append('path')
                .attr('class', 'line')
                .merge(lines)
                .attr('id', ({topic}) => topic)
                .attr('d', ({dates}) => topicLine(dates))
                .style('stroke', (d) => (
                    dataByTopic.length === 1 ? `url(#${lineGradientId})` : getLineColor(d)
                ));

            lines
                .exit()
                .remove();
        }
76518
function draw(renderer, text, x, y) {
         // allows to provide backward compatibility when
         // adding Bitmap Font to an object container
         if (typeof this.ancestor === "undefined") {
           // update cache
           this.setText(text); // force update bounds

           this.update(0); // save the previous global alpha value

           var _alpha = renderer.globalAlpha();

           renderer.setGlobalAlpha(_alpha * this.getOpacity());
         } else {
           // added directly to an object container
           x = this.pos.x;
           y = this.pos.y;
         }

         var strings = ("" + this._text).split("\n");

         var lX = x;
         var stringHeight = measureTextHeight(this);
         var maxWidth = 0;

         for (var i = 0; i < strings.length; i++) {
           x = lX;
           var string = me.utils.string.trimRight(strings[i]); // adjust x pos based on alignment value

           var stringWidth = measureTextWidth(this, string);

           switch (this.textAlign) {
             case "right":
               x -= stringWidth;
               break;

             case "center":
               x -= stringWidth * 0.5;
               break;

             default:
               break;
           } // adjust y pos based on alignment value


           switch (this.textBaseline) {
             case "middle":
               y -= stringHeight * 0.5;
               break;

             case "ideographic":
             case "alphabetic":
             case "bottom":
               y -= stringHeight;
               break;

             default:
               break;
           } // update initial position if required


           if (this.isDirty === true && typeof this.ancestor === "undefined") {
             if (i === 0) {
               this.pos.y = y;
             }

             if (maxWidth < stringWidth) {
               maxWidth = stringWidth;
               this.pos.x = x;
             }
           } // draw the string


           var lastGlyph = null;

           for (var c = 0, len = string.length; c < len; c++) {
             // calculate the char index
             var ch = string.charCodeAt(c);
             var glyph = this.fontData.glyphs[ch];
             var glyphWidth = glyph.width;
             var glyphHeight = glyph.height;
             var kerning = lastGlyph && lastGlyph.kerning ? lastGlyph.getKerning(ch) : 0; // draw it

             if (glyphWidth !== 0 && glyphHeight !== 0) {
               // some browser throw an exception when drawing a 0 width or height image
               renderer.drawImage(this.fontImage, glyph.x, glyph.y, glyphWidth, glyphHeight, x + glyph.xoffset, y + glyph.yoffset * this.fontScale.y, glyphWidth * this.fontScale.x, glyphHeight * this.fontScale.y);
             } // increment position


             x += (glyph.xadvance + kerning) * this.fontScale.x;
             lastGlyph = glyph;
           } // increment line


           y += stringHeight;
         }

         if (typeof this.ancestor === "undefined") {
           // restore the previous global alpha value
           renderer.setGlobalAlpha(_alpha);
         } // clear the dirty flag


         this.isDirty = false;
       }
1190734
function _drawLine(canvas, ctx, params, path) {
	var l,
		lx, ly;
	l = 2;
	_addStartArrow(
		canvas, ctx,
		params, path,
		path.x2 + params.x,
		path.y2 + params.y,
		path.x1 + params.x,
		path.y1 + params.y
	);
	if (path.x1 !== undefined && path.y1 !== undefined) {
		ctx.moveTo(path.x1 + params.x, path.y1 + params.y);
	}
	while (true) {
		// Calculate next coordinates
		lx = path['x' + l];
		ly = path['y' + l];
		// If coordinates are given
		if (lx !== undefined && ly !== undefined) {
			// Draw next line
			ctx.lineTo(lx + params.x, ly + params.y);
			l += 1;
		} else {
			// Otherwise, stop drawing
			break;
		}
	}
	l -= 1;
	// Optionally add arrows to path
	_addEndArrow(
		canvas, ctx,
		params,
		path,
		path['x' + (l - 1)] + params.x,
		path['y' + (l - 1)] + params.y,
		path['x' + l] + params.x,
		path['y' + l] + params.y
	);
}
32424
function Shaded_box($text, $font = '', $fontstyle = 'B', $szfont = '', $width = '70%', $style = 'DF', $radius = 2.5, $fill = '#FFFFFF', $color = '#000000', $pad = 2)
	{
		// F (shading - no line),S (line, no shading),DF (both)
		if (empty($this->directWrite)) {
			$this->directWrite = new DirectWrite($this, $this->otl, $this->sizeConverter, $this->colorConverter);
		}
		$this->directWrite->Shaded_box($text, $font, $fontstyle, $szfont, $width, $style, $radius, $fill, $color, $pad);
	}
1018976
function () {
		var series = this,
			chart = series.chart,
			renderer = chart.renderer,
			groupTranslation,
			//center,
			graphic,
			group,
			shadow = series.options.shadow,
			shadowGroup,
			shapeArgs;


		// draw the slices
		each(series.data, function (point) {
			graphic = point.graphic;
			shapeArgs = point.shapeArgs;
			group = point.group;
			shadowGroup = point.shadowGroup;

			// put the shadow behind all points
			if (shadow && !shadowGroup) {
				shadowGroup = point.shadowGroup = renderer.g('shadow')
					.attr({ zIndex: 4 })
					.add();
			}

			// create the group the first time
			if (!group) {
				group = point.group = renderer.g('point')
					.attr({ zIndex: 5 })
					.add();
			}

			// if the point is sliced, use special translation, else use plot area traslation
			groupTranslation = point.sliced ? point.slicedTranslation : [chart.plotLeft, chart.plotTop];
			group.translate(groupTranslation[0], groupTranslation[1]);
			if (shadowGroup) {
				shadowGroup.translate(groupTranslation[0], groupTranslation[1]);
			}


			// draw the slice
			if (graphic) {
				graphic.animate(shapeArgs);
			} else {
				point.graphic =
					renderer.arc(shapeArgs)
					.attr(extend(
						point.pointAttr[NORMAL_STATE],
						{ 'stroke-linejoin': 'round' }
					))
					.add(point.group)
					.shadow(shadow, shadowGroup);
			}

			// detect point specific visibility
			if (point.visible === false) {
				point.setVisible(false);
			}

		});

	}
1138098
function drawLinearBarHighlights(context, options) {
    let {isVertical, width, length, barWidth, barOffset, barMargin,
        X, Y, ticksLength, ticksPadding} = context.barDimensions;
    let hlWidth = width * (parseFloat(options.highlightsWidth) || 0) / 100;

    if (!options.highlights || !hlWidth) return ;

    let hasLeft = options.tickSide !== 'right';
    let hasRight = options.tickSide !== 'left';
    let i = 0;
    let s = options.highlights.length;
    let tickOffset = (width - barWidth) / 2;
    let interval = options.maxValue - options.minValue;
    //noinspection JSUnresolvedFunction
    let eX = round(isVertical ? X + tickOffset : X + barMargin + barOffset);
    let eH = hlWidth;
    let eY = isVertical ? Y + length - barMargin - barOffset: Y + tickOffset;
    //noinspection JSUnresolvedFunction
    let hLeft = round((options.ticksWidth / 100 + ticksPadding) * width)
        + (hlWidth - options.ticksWidth / 100 * width);
    //noinspection JSUnresolvedFunction
    let hRight = round(barWidth + ticksPadding * width);

    context.save();

    for (; i < s; i++) {
        let entry = options.highlights[i];
        //noinspection JSUnresolvedFunction
        let eStart = ticksLength * abs(options.minValue - entry.from) /
            interval;
        //noinspection JSUnresolvedFunction
        let eW = ticksLength * abs((entry.to - entry.from) / interval);

        context.beginPath();
        context.fillStyle = entry.color;

        if (isVertical) {
            if (hasLeft)
                context.rect(eX - hLeft, eY - eStart, eH, -eW);

            if (hasRight)
                context.rect(eX + hRight, eY - eStart, eH, -eW);
        }

        else {
            if (hasLeft)
                context.rect(eX + eStart, eY - hLeft, eW, eH);

            if (hasRight)
                context.rect(eX + eStart, eY + hRight, eW, eH);
        }

        context.fill();
        context.closePath();
    }
}
702624
function (d, context) {
                    dimple._drawMarkers(d, chart, series, duration, className, graded, onEnter(d), onLeave(d), context);
                }
1089241
function() {
		var d = 7; // arrow width/2
      var redim = d+3; //we have to make the canvas a little bigger because of arrows
      var margin=[4+redim,4+redim];

      // Get the positions of the terminals
      var p1 = this.terminal1.getXY();
      var p2 = this.terminal2.getXY();

      var distance=Math.sqrt(Math.pow(p1[0]-p2[0],2)+Math.pow(p1[1]-p2[1],2));

      var min=[ Math.min(p1[0],p2[0])-margin[0], Math.min(p1[1],p2[1])-margin[1]];
      var max=[ Math.max(p1[0],p2[0])+margin[0], Math.max(p1[1],p2[1])+margin[1]];

		// Store the min, max positions to display the label later
		this.min = min;
		this.max = max;      

      // Redimensionnement du canvas
      
      var lw=Math.abs(max[0]-min[0])+redim;
      var lh=Math.abs(max[1]-min[1])+redim;

      p1[0]=p1[0]-min[0];
      p1[1]=p1[1]-min[1];
      p2[0]=p2[0]-min[0];
      p2[1]=p2[1]-min[1];

      this.SetCanvasRegion(min[0],min[1],lw,lh);

      var ctxt=this.getContext();
      
      // Draw the border
      ctxt.lineCap=this.bordercap;
      ctxt.strokeStyle=this.bordercolor;
      ctxt.lineWidth=this.width+this.borderwidth*2;
      ctxt.beginPath();
      ctxt.moveTo(p1[0],p1[1]);
      ctxt.lineTo(p2[0],p2[1]);
      ctxt.stroke();

      // Draw the inner bezier curve
      ctxt.lineCap=this.cap;
      ctxt.strokeStyle=this.color;
      ctxt.lineWidth=this.width;
      ctxt.beginPath();
      ctxt.moveTo(p1[0],p1[1]);
      ctxt.lineTo(p2[0],p2[1]);
      ctxt.stroke();

		/* start drawing arrows */
		var t1 = p1;
		var t2 = p2;

		var z = [0,0]; //point on the wire with constant distance (dlug) from terminal2
		var dlug = 20; //arrow length
		var t = (distance === 0) ? 0 : 1-(dlug/distance);
		z[0] = Math.abs( t1[0] +  t*(t2[0]-t1[0]) );
		z[1] = Math.abs( t1[1] + t*(t2[1]-t1[1]) );	

		//line which connects the terminals: y=ax+b
		var a,b;
		var W = t1[0] - t2[0];
		var Wa = t1[1] - t2[1];
		var Wb = t1[0]*t2[1] - t1[1]*t2[0];
		if (W !== 0) {
			a = Wa/W;
			b = Wb/W;
		}
		else {
			a = 0;
		}
		//line perpendicular to the main line: y = aProst*x + b
		var aProst, bProst;
		if (a === 0) {
			aProst = 0;
		}
		else {
			aProst = -1/a;
		}
		bProst = z[1] - aProst*z[0]; //point z lays on this line

		//we have to calculate coordinates of 2 points, which lay on perpendicular line and have the same distance (d) from point z
		var A = 1 + Math.pow(aProst,2);
		var B = 2*aProst*bProst - 2*z[0] - 2*z[1]*aProst;
		var C = -2*z[1]*bProst + Math.pow(z[0],2) + Math.pow(z[1],2) - Math.pow(d,2) + Math.pow(bProst,2);
		var delta = Math.pow(B,2) - 4*A*C;
		if (delta < 0) { return; }

		var x1 = (-B + Math.sqrt(delta)) / (2*A);
		var x2 = (-B - Math.sqrt(delta)) / (2*A);	 
		var y1 = aProst*x1 + bProst;
		var y2 = aProst*x2 + bProst;

		if(t1[1] == t2[1]) {
			var o = (t1[0] > t2[0]) ? 1 : -1;
			x1 = t2[0]+o*dlug;
			x2 = x1;
			y1 -= d;
			y2 += d;
		}

		//triangle fill
		ctxt.fillStyle = this.color;
		ctxt.beginPath();
		ctxt.moveTo(t2[0],t2[1]);
		ctxt.lineTo(x1,y1);
		ctxt.lineTo(x2,y2);
		ctxt.fill();

		//triangle border	
		ctxt.strokeStyle = this.bordercolor;
		ctxt.lineWidth = this.borderwidth;
		ctxt.beginPath();
		ctxt.moveTo(t2[0],t2[1]);
		ctxt.lineTo(x1,y1);
		ctxt.lineTo(x2,y2);
		ctxt.lineTo(t2[0],t2[1]);
		ctxt.stroke();
   }
884648
function drawLinearTick(context, x1, y1, x2, y2) {
    context.beginPath();

    context.moveTo(x1, y1);
    context.lineTo(x2, y2);
    context.stroke();

    context.closePath();
    context.save();
}
1342756
function () {

      function draw(color, n) {
        n = Math.max(parseInt(n), 0);

        write(' ');
        write('\u001b[' + color + 'm' + n + '\u001b[0m');
        write('\n');
      }

      draw(colors.green, this.passed);
      draw(colors.fail, this.failed);
      draw(colors.pending, this.pending + ' ');
      write('\n');

      cursor.up(this.numberOfLines);
    }
428168
function drawSteps(){
            let steps = svg.select('.chart-group').selectAll('.step').data(data);

            // Enter
            steps.enter()
              .append('rect')
                .classed('step', true)
                .attr('x', chartWidth) // Initially drawing the steps at the end of Y axis
                .attr('y', ({value}) => yScale(value))
                .attr('width', xScale.bandwidth())
                .attr('height', (d) => (chartHeight - yScale(d.value)))
                .on('mouseover', function(d) {
                    handleMouseOver(this, d, chartWidth, chartHeight);
                })
                .on('mousemove', function(d) {
                    handleMouseMove(this, d, chartWidth, chartHeight);
                })
                .on('mouseout', function(d) {
                    handleMouseOut(this, d, chartWidth, chartHeight);
                })
              .merge(steps)
                .transition()
                .ease(ease)
                .attr('x', ({key}) => xScale(key))
                .attr('y', function(d) {
                    return yScale(d.value);
                })
                .attr('width', xScale.bandwidth())
                .attr('height', function(d) {
                    return chartHeight - yScale(d.value);
                });

            // Exit
            steps.exit()
                .transition()
                .style('opacity', 0)
                .remove();
        }
1299995
function() {
        var width = canvasWidth,
          height = canvasHeight,
          positionX = canvasWidth / 2,
          positionY = canvasHeight / 2,
          alphaPercentage = (width / 100) * self.currentPercentage;

        //clearing canvas from everithing
        clear();
        //let's start drawning
        ctx.restore();
        ctx.beginPath();
        //draw percentage text
        ctx.font = font;
        ctx.fillStyle = color;
        ctx.textAlign = "center";
        ctx.fillText((self.currentPercentage | 0) + "%", positionX, positionY - (lineWidth + 10));
        //width of the preloader line
        ctx.lineWidth = lineWidth;
        //color of preloader line
        ctx.strokeStyle = color;
        if (glowColor) {
          ctx.shadowOffsetX = 0;
          ctx.shadowOffsetY = 0;
          ctx.shadowBlur = 10;
          ctx.shadowColor = glowColor;
        }
        ctx.moveTo(positionX - (width / 2), positionY);
        ctx.lineTo(alphaPercentage, positionY);
        ctx.stroke();

        ctx.save();
      }