schplurtz / a2s

DokuWiki asciitosvg plugin
GNU General Public License v2.0
3 stars 1 forks source link

Could we do some workaround to drop the marker for dw2pdf? #8

Open zeerd opened 4 years ago

zeerd commented 4 years ago

Hello!

As the mPDF won't support marker as they said at the mPDF Manual. I'd like to do something like the codes below, to refuse the marker but use some more paths.

But, my php is only at a beginner level. And I am not very sure if there need four branch in each draw function.

Could you have a look at this and found some way to make the dw2pdf usefull?

--- ASCIIToSVG.php.orig 2020-04-21 11:45:31.105630518 +0800
+++ ASCIIToSVG.php      2020-04-21 16:34:30.261628449 +0800
@@ -2474,6 +2474,92 @@
     }
   }

+  public function drawIArrow($fx, $fy, $tx, $ty) {
+    $l = 8;
+    // <
+    if($fx < $tx) {
+      $ax0 = $fx - $l/2;
+      $ay0 = $fy;
+      $ax1 = $fx + $l;
+      $ay1 = $fy - $l;
+      $ax2 = $fx + $l;
+      $ay2 = $fy + $l;
+    }
+    // >
+    else if($fx > $tx) {
+      $ax0 = $fx + $l/2;
+      $ay0 = $fy;
+      $ax1 = $fx - $l;
+      $ay1 = $fy - $l;
+      $ax2 = $fx - $l;
+      $ay2 = $fy + $l;
+    }
+    // ^
+    if($fy < $ty) {
+      $ax0 = $fx;
+      $ay0 = $fy - $l/2;
+      $ax1 = $fx - $l;
+      $ay1 = $fy + $l;
+      $ax2 = $fx + $l;
+      $ay2 = $fy + $l;
+    }
+    // v
+    else if($fy > $ty) {
+      $ax0 = $fx;
+      $ay0 = $fy + $l/2;
+      $ax1 = $fx - $l;
+      $ay1 = $fy - $l;
+      $ax2 = $fx + $l;
+      $ay2 = $fy - $l;
+    }
+
+    //return "M {$ax0} {$ay0} L {$ax1} {$ay1} L {$ax2} {$ay2} Z ";
+    return "M {$ax0} {$ay0} L {$fx} {$fy} M {$ax0} {$ay0} L {$ax1} {$ay1} M {$ax0} {$ay0} {$ax2} {$ay2} ";
+  }
+
+  public function drawArrow($fx, $fy, $tx, $ty) {
+    $l = 8;
+    // <
+    if($fx > $tx) {
+      $ax0 = $tx - $l/2;
+      $ay0 = $ty;
+      $ax1 = $tx + $l;
+      $ay1 = $ty - $l;
+      $ax2 = $tx + $l;
+      $ay2 = $ty + $l;
+    }
+    // >
+    else if($fx < $tx) {
+      $ax0 = $tx + $l/2;
+      $ay0 = $ty;
+      $ax1 = $tx - $l;
+      $ay1 = $ty - $l;
+      $ax2 = $tx - $l;
+      $ay2 = $ty + $l;
+    }
+    // ^
+    if($fy > $ty) {
+      $ax0 = $tx;
+      $ay0 = $ty - $l/2;
+      $ax1 = $tx - $l;
+      $ay1 = $ty + $l;
+      $ax2 = $tx + $l;
+      $ay2 = $ty + $l;
+    }
+    // v
+    else if($fy < $ty) {
+      $ax0 = $tx;
+      $ay0 = $ty + $l/2;
+      $ax1 = $tx - $l;
+      $ay1 = $ty - $l;
+      $ax2 = $tx + $l;
+      $ay2 = $ty - $l;
+    }
+
+    // return "M {$ax0} {$ay0} L {$ax1} {$ay1} L {$ax2} {$ay2} Z ";
+    return "M {$ax0} {$ay0} L {$tx} {$ty} M {$ax0} {$ay0} L {$ax1} {$ay1} M {$ax0} {$ay0} {$ax2} {$ay2} ";
+  }
+
   public function render() {
     $startPoint = array_shift($this->points);
     $endPoint = $this->points[count($this->points) - 1];
@@ -2589,6 +2675,8 @@
       $path = "M {$startPoint->x} {$startPoint->y} ";
     }

+
+
     $prevP = $startPoint;
     $bound = count($this->points);
     for ($i = 0; $i < $bound; $i++) {
@@ -2666,15 +2754,26 @@

     /* Add markers if necessary. */
     if ($startPoint->flags & Point::SMARKER) {
-      $this->options["marker-start"] = "url(#Pointer)";
+      //$this->options["marker-start"] = "url(#Pointer)";
+      $path .= $this->drawArrow($startPoint->x, $startPoint->y, $this->points[0]->x, $this->points[0]->y);
     } elseif ($startPoint->flags & Point::IMARKER) {
-      $this->options["marker-start"] = "url(#iPointer)";
+      //$this->options["marker-start"] = "url(#iPointer)";
+      $path .= $this->drawIArrow($startPoint->x, $startPoint->y, $this->points[0]->x, $this->points[0]->y);
     }

     if ($endPoint->flags & Point::SMARKER) {
-      $this->options["marker-end"] = "url(#Pointer)";
+      //$this->options["marker-end"] = "url(#Pointer)";
+      if($bound == 1) {
+        $path .= $this->drawArrow($startPoint->x, $startPoint->y, $endPoint->x, $endPoint->y);
+      }
+      else {
+        $j = count($this->points) - 2;
+        $path .= $this->drawArrow($this->points[$j]->x, $this->points[$j]->y, $endPoint->x, $endPoint->y);
+      }
     } elseif ($endPoint->flags & Point::IMARKER) {
-      $this->options["marker-end"] = "url(#iPointer)";
+      //$this->options["marker-end"] = "url(#iPointer)";
+      $j = count($this->points) - 2;
+      $path .= $this->drawIArrow($endPoint->x, $endPoint->y, $this->points[$j]->x, $this->points[$j]->y);
     }

     /*

I tested this with the codes below, seems it work.

<a2s>
--->  <---   |      ^
             |      |
  |  ^       +--> --+
  |  |
  v  |       +-- |<--+
             |   |   |
===> <===    v       |
            ---     ---
  :  ^       |       ^
  :  :       |   |   |
  v  :       +-->| --+
</a2s>

Ref : splitbrain/dokuwiki-plugin-dw2pdf#396

schplurtz commented 4 years ago

Hi,

I did not want to modify ASCIIToSVG.php as this is used as a library that I include in my very modest work. However, ASCIIToSVG is no more developed, so I guess I could add some little workarounds in the original code.

I'll take a look into it, not promising anything.

Thanks for your submission.

schplurtz commented 4 years ago

Hum, I won't do it like this. It changes the kind of arrow. And there are problems with oblique. See current vs your proposed changes. If I'm going to accept this, the change in the code must result in identical aspect.

<a2s>
--->  <---   |      ^      \     |     /  ^     ^     ^
             |      |       \    |    /    \    |    /
  |  ^       +--> --+        \   |   /      \   |   /
  |  |                        \  |  /        \  |  /
  v  |       +-- |<--+         \ | /          \ | /
             |   |   |          vvv            \|/
===> <===    v       |     ----->o<-----  <-----o----->
            ---     ---         ^^^            /|\
  :  ^       |       ^         / | \          / | \
  :  :       |   |   |        /  |  \        /  |  \
  v  :       +-->| --+       /   |   \      /   |   \
                            /    |    \    /    |    \
                           /     |     \  v     v     v
</a2s>
image image
zeerd commented 4 years ago

OK, I 'll check this. I forgot the lines at the right side....

schplurtz commented 4 years ago

On my side, I've also tried to solve this issue. There is still work to do, but a first usable code is available in the arrow-separate branch.

I can't test this with dw2pdf, I just installed it but latest dw2pdf has problem with SVG (dw2pdf issue 401)

Can you try the code on this branch ?

zeerd commented 4 years ago

I didn't find the way to use the dw2dpf directly. The manual of dw2pdf is not so firendly for a non-php user. So all my testing is based on doku+a2s+dw2dpf.

And I got some new functions for those arrows with some terrible variable-names(I am not a English speaker and have very little knowledge of these mathematical terms).

  /* For the arraws comes from angled lines.
   * I can not draw a picture with those comments, so I give a svg to made it clean.
   * <svg>
   * <line x1="150" y1="10" x2="50" y2="10"  style="stroke:gray;"></line>
   * <line x1="100" y1="10" x2="100" y2="100"  style="stroke:gray;"></line>
   * <line x1="100" y1="10" x2="61" y2="82"  style="stroke:black;"></line>
   * <line x1="100" y1="10" x2="78" y2="18"  style="stroke:black;"></line>
   * <line x1="100" y1="10" x2="108" y2="32"  style="stroke:black;"></line>
   * </svg>
   *
   * The angle of the angled line is fixed in the a2s,
   * it is about 28.44 degrees from the vertical line.
   * And we can get the angle used to calc is 90 - 45 - 28.44 = 16.56
   * So , we could calc the points of the end of arrow-lines by trigonometric functions.
   */

  public function drawIArrow($fx, $fy, $tx, $ty) {
    $cl = 14;
    $l = $cl * sin(deg2rad(45));  // the edge of the trigonometric for arrow without angle
    $hll = $cl * cos(deg2rad(28.44)); // used to draw an extension cord.
    $hls = $cl * sin(deg2rad(28.44));
    $ll = $cl * cos(deg2rad(16.56)); // the long edge of the trigonometric for arrow with angle
    $ls = $cl * sin(deg2rad(16.56)); // the short edge of the trigonometric for arrow with angle
    // <
    if($fx < $tx) {
      $ax0 = $fx - $l/2;
      $ay0 = $fy;
      $ax1 = $fx + $l;
      $ay1 = $fy - $l;
      $ax2 = $fx + $l;
      $ay2 = $fy + $l;
    }
    // >
    else if($fx > $tx) {
      $ax0 = $fx + $l/2;
      $ay0 = $fy;
      $ax1 = $fx - $l;
      $ay1 = $fy - $l;
      $ax2 = $fx - $l;
      $ay2 = $fy + $l;
    }
    // ^
    if($fy < $ty) {
      $ax0 = $fx;
      $ay0 = $fy - $l/2;
      $ax1 = $fx - $l;
      $ay1 = $fy + $l;
      $ax2 = $fx + $l;
      $ay2 = $fy + $l;
      if($fx < $tx) { // left top
        $ax0 = $fx - $hls/2;
        $ay0 = $fy - $hll/2;
        $ax1 = $ax0 - $ls;
        $ay1 = $ay0 + $ll;
        $ax2 = $ax0 + $ll;
        $ay2 = $ay0 + $ls;
      }

    }
    // v
    else if($fy > $ty) {
      $ax0 = $fx;
      $ay0 = $fy + $l/2;
      $ax1 = $fx - $l;
      $ay1 = $fy - $l;
      $ax2 = $fx + $l;
      $ay2 = $fy - $l;
      if($fx < $tx) { // left bottom
        $ax0 = $fx - $hls/2;
        $ay0 = $fy + $hll/2;
        $ax1 = $ax0 - $ls;
        $ay1 = $ay0 - $ll;
        $ax2 = $ax0 + $ll;
        $ay2 = $ay0 - $ls;
      }
    }

    //return "M {$ax0} {$ay0} L {$ax1} {$ay1} L {$ax2} {$ay2} Z ";
    return "M {$ax0} {$ay0} L {$fx} {$fy} M {$ax0} {$ay0} L {$ax1} {$ay1} M {$ax0} {$ay0} {$ax2} {$ay2} ";
  }

  public function drawArrow($fx, $fy, $tx, $ty) {
    $cl = 14;
    $l = $cl * sin(deg2rad(45));
    $hll = $cl * cos(deg2rad(28.44));
    $hls = $cl * sin(deg2rad(28.44));
    $ll = $cl * cos(deg2rad(16.56));
    $ls = $cl * sin(deg2rad(16.56));
    // <
    if($fx > $tx) {
      $ax0 = $tx - $l/2;
      $ay0 = $ty;
      $ax1 = $tx + $l;
      $ay1 = $ty - $l;
      $ax2 = $tx + $l;
      $ay2 = $ty + $l;
    }
    // >
    else if($fx < $tx) {
      $ax0 = $tx + $l/2;
      $ay0 = $ty;
      $ax1 = $tx - $l;
      $ay1 = $ty - $l;
      $ax2 = $tx - $l;
      $ay2 = $ty + $l;
    }
    // ^
    if($fy > $ty) {
      $ax0 = $tx;
      $ay0 = $ty - $l/2;
      $ax1 = $tx - $l;
      $ay1 = $ty + $l;
      $ax2 = $tx + $l;
      $ay2 = $ty + $l;
      if($fx < $tx) { // right top
        $ax0 = $tx + $hls/2;
        $ay0 = $ty - $hll/2;
        $ax1 = $ax0 + $ls;
        $ay1 = $ay0 + $ll;
        $ax2 = $ax0 - $ll;
        $ay2 = $ay0 + $ls;
      }
    }
    // v
    else if($fy < $ty) {
      $ax0 = $tx;
      $ay0 = $ty + $l/2;
      $ax1 = $ax0 - $l;
      $ay1 = $ay0 - $l;
      $ax2 = $ax0 + $l;
      $ay2 = $ay0 - $l;
      if($fx < $tx) { // right bottom
        $ax0 = $tx + $hls/2;
        $ay0 = $ty + $hll/2;
        $ax1 = $ax0 + $ls;
        $ay1 = $ay0 - $ll;
        $ax2 = $ax0 - $ll;
        $ay2 = $ay0 - $ls;
      }
    }

    // return "M {$ax0} {$ay0} L {$ax1} {$ay1} L {$ax2} {$ay2} Z ";
    return "M {$ax0} {$ay0} L {$tx} {$ty} M {$ax0} {$ay0} L {$ax1} {$ay1} M {$ax0} {$ay0} {$ax2} {$ay2} ";
  }