www

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

menclose.js (8516B)


      1 /* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */
      2 /* vim: set ts=2 et sw=2 tw=80: */
      3 
      4 /*************************************************************
      5  *
      6  *  MathJax/jax/output/SVG/autoload/menclose.js
      7  *  
      8  *  Implements the SVG output for <menclose> elements.
      9  *
     10  *  ---------------------------------------------------------------------
     11  *  
     12  *  Copyright (c) 2011-2015 The MathJax Consortium
     13  * 
     14  *  Licensed under the Apache License, Version 2.0 (the "License");
     15  *  you may not use this file except in compliance with the License.
     16  *  You may obtain a copy of the License at
     17  * 
     18  *      http://www.apache.org/licenses/LICENSE-2.0
     19  * 
     20  *  Unless required by applicable law or agreed to in writing, software
     21  *  distributed under the License is distributed on an "AS IS" BASIS,
     22  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     23  *  See the License for the specific language governing permissions and
     24  *  limitations under the License.
     25  */
     26 
     27 MathJax.Hub.Register.StartupHook("SVG Jax Ready",function () {
     28   var VERSION = "2.6.0";
     29   var MML = MathJax.ElementJax.mml,
     30       SVG = MathJax.OutputJax.SVG,
     31       BBOX = SVG.BBOX;
     32       
     33   BBOX.ELLIPSE = BBOX.Subclass({
     34     type: "ellipse", removeable: false,
     35     Init: function (h,d,w,t,color,def) {
     36       if (def == null) {def = {}}; def.fill = "none";
     37       if (color) {def.stroke = color}
     38       def["stroke-width"] = t.toFixed(2).replace(/\.?0+$/,"");
     39       def.cx = Math.floor(w/2); def.cy = Math.floor((h+d)/2-d);
     40       def.rx = Math.floor((w-t)/2); def.ry = Math.floor((h+d-t)/2);
     41       this.SUPER(arguments).Init.call(this,def);
     42       this.w = this.r = w; this.h = this.H = h;
     43       this.d = this.D = d; this.l = 0;
     44     }
     45   });
     46   
     47   BBOX.DLINE = BBOX.Subclass({
     48     type: "line", removeable: false,
     49     Init: function (h,d,w,t,color,updown,def) {
     50       if (def == null) {def = {}}; def.fill = "none";
     51       if (color) {def.stroke = color}
     52       def["stroke-width"] = t.toFixed(2).replace(/\.?0+$/,"");
     53       if (updown == "up") {
     54         def.x1 = Math.floor(t/2); def.y1 = Math.floor(t/2-d);
     55         def.x2 = Math.floor(w-t/2); def.y2 = Math.floor(h-t/2);
     56       } else {
     57         def.x1 = Math.floor(t/2); def.y1 = Math.floor(h-t/2);
     58         def.x2 = Math.floor(w-t/2); def.y2 = Math.floor(t/2-d);
     59       }
     60       this.SUPER(arguments).Init.call(this,def);
     61       this.w = this.r = w; this.h = this.H = h;
     62       this.d = this.D = d; this.l = 0;
     63     }
     64   });
     65   
     66   BBOX.FPOLY = BBOX.Subclass({
     67     type: "polygon", removeable: false,
     68     Init: function (points,color,def) {
     69       if (def == null) {def = {}}
     70       if (color) {def.fill = color}
     71       var P = [], mx = 100000000, my = mx, Mx = -mx, My = Mx;
     72       for (var i = 0, m = points.length; i < m; i++) {
     73         var x = points[i][0], y = points[i][1];
     74         if (x > Mx) {Mx = x}; if (x < mx) {mx = x}
     75         if (y > My) {My = y}; if (y < my) {my = y}
     76         P.push(Math.floor(x)+","+Math.floor(y));
     77       }
     78       def.points = P.join(" ");
     79       this.SUPER(arguments).Init.call(this,def);
     80       this.w = this.r = Mx; this.h = this.H = My;
     81       this.d = this.D = -my; this.l = -mx;
     82     }
     83   });
     84 
     85   BBOX.PPATH = BBOX.Subclass({
     86     type: "path", removeable: false,
     87     Init: function (h,d,w,p,t,color,def) {
     88       if (def == null) {def = {}}; def.fill = "none";
     89       if (color) {def.stroke = color}
     90       def["stroke-width"] = t.toFixed(2).replace(/\.?0+$/,"");
     91       def.d = p;
     92       this.SUPER(arguments).Init.call(this,def);
     93       this.w = this.r = w; this.h = this.H = h+d;
     94       this.d = this.D = this.l = 0; this.y = -d;
     95     }
     96   });
     97   
     98   MML.menclose.Augment({
     99     toSVG: function (HW,DD) {
    100       this.SVGgetStyles();
    101 
    102       var svg = this.SVG(), scale = this.SVGgetScale(svg);
    103       this.SVGhandleSpace(svg);
    104       var base = this.SVGdataStretched(0,HW,DD);
    105 
    106       var values = this.getValues("notation","thickness","padding","mathcolor","color");
    107       if (values.color && !this.mathcolor) {values.mathcolor = values.color}
    108       if (values.thickness == null) {values.thickness = ".075em"}
    109       if (values.padding == null)   {values.padding   = ".2em"}
    110       var mu = this.SVGgetMu(svg);
    111       var p = SVG.length2em(values.padding,mu,1/SVG.em) * scale;  // padding for enclosure
    112       var t = SVG.length2em(values.thickness,mu,1/SVG.em);        // thickness of lines
    113       t = Math.max(1/SVG.em,t);  // see issue #414
    114       var H = base.h+p+t, D = base.d+p+t, W = base.w+2*(p+t);
    115       var dx = 0, w, h, i, m, borders = [false,false,false,false];
    116       if (!values.mathcolor) {values.mathcolor = "black"}
    117 
    118       // perform some reduction e.g. eliminate duplicate notations.
    119       var nl = MathJax.Hub.SplitList(values.notation), notation = {};
    120       for (i = 0, m = nl.length; i < m; i++) notation[nl[i]] = true;
    121       if (notation[MML.NOTATION.UPDIAGONALARROW]) notation[MML.NOTATION.UPDIAGONALSTRIKE] = false;
    122       
    123       for (var n in notation) {
    124         if (!notation.hasOwnProperty(n) || !notation[n]) continue;
    125         switch (n) {
    126           case MML.NOTATION.BOX:
    127             borders = [true,true,true,true];
    128             break;
    129 
    130           case MML.NOTATION.ROUNDEDBOX:
    131             svg.Add(BBOX.FRAME(H,D,W,t,"solid",values.mathcolor,
    132                      {rx:Math.floor(Math.min(H+D-t,W-t)/4)}));
    133             break;
    134             
    135           case MML.NOTATION.CIRCLE:
    136             svg.Add(BBOX.ELLIPSE(H,D,W,t,values.mathcolor));
    137             break;
    138 
    139           case MML.NOTATION.ACTUARIAL:
    140             borders[0] = true;
    141           case MML.NOTATION.RIGHT:
    142             borders[1] = true;
    143             break;
    144 
    145           case MML.NOTATION.LEFT:
    146             borders[3] = true;
    147             break;
    148             
    149           case MML.NOTATION.TOP:
    150             borders[0] = true;
    151             break;
    152             
    153           case MML.NOTATION.BOTTOM:
    154             borders[2] = true;
    155             break;
    156             
    157           case MML.NOTATION.VERTICALSTRIKE:
    158             svg.Add(BBOX.VLINE(H+D,t,"solid",values.mathcolor),(W-t)/2,-D);
    159             break;
    160             
    161           case MML.NOTATION.HORIZONTALSTRIKE:
    162             svg.Add(BBOX.HLINE(W,t,"solid",values.mathcolor),0,(H+D-t)/2-D);
    163             break;
    164 
    165           case MML.NOTATION.UPDIAGONALSTRIKE:
    166             svg.Add(BBOX.DLINE(H,D,W,t,values.mathcolor,"up"));
    167             break;
    168 
    169           case MML.NOTATION.UPDIAGONALARROW:
    170               var l = Math.sqrt(W*W + (H+D)*(H+D)), f = 1/l * 10/SVG.em * t/.075;
    171               w = W * f; h = (H+D) * f; var x = .4*h;
    172               svg.Add(BBOX.DLINE(H-.5*h,D,W-.5*w,t,values.mathcolor,"up"));
    173               svg.Add(BBOX.FPOLY(
    174                 [[x+w,h], [x-.4*h,.4*w], [x+.3*w,.3*h], [x+.4*h,-.4*w], [x+w,h]],
    175                 values.mathcolor),W-w-x,H-h);
    176             break;
    177 
    178           case MML.NOTATION.DOWNDIAGONALSTRIKE:
    179             svg.Add(BBOX.DLINE(H,D,W,t,values.mathcolor,"down"));
    180             break;
    181             
    182           case MML.NOTATION.PHASORANGLE:
    183             borders[2] = true; W -= 2*p; p = (H+D)/2; W += p;
    184             svg.Add(BBOX.DLINE(H,D,p,t,values.mathcolor,"up"));
    185             break;
    186 
    187           case MML.NOTATION.MADRUWB:
    188             borders[1] = borders[2] = true;
    189             break;
    190 
    191           case MML.NOTATION.RADICAL:
    192             svg.Add(BBOX.PPATH(H,D,W,
    193               "M "+this.SVGxy(t/2,.4*(H+D)) +
    194               " L "+this.SVGxy(p,t/2) +
    195               " L "+this.SVGxy(2*p,H+D-t/2) +
    196               " L "+this.SVGxy(W,H+D-t/2),
    197               t,values.mathcolor),0,t);
    198             dx = p;
    199             break;
    200             
    201           case MML.NOTATION.LONGDIV:
    202             svg.Add(BBOX.PPATH(H,D,W,
    203               "M "+this.SVGxy(t/2,t/2) +
    204               " a "+this.SVGxy(p,(H+D)/2-2*t) + " 0 0,1 " + this.SVGxy(t/2,H+D-t) +
    205               " L "+this.SVGxy(W,H+D-t/2),
    206               t,values.mathcolor),0,t/2);
    207             dx = p;
    208             break;
    209         }
    210       }
    211       var sides = [["H",W,0,H-t],["V",H+D,W-t,-D],["H",W,0,-D],["V",H+D,0,-D]];
    212       for (i = 0; i < 4; i++) {
    213         if (borders[i]) {
    214           var side = sides[i];
    215           svg.Add(BBOX[side[0]+"LINE"](side[1],t,"solid",values.mathcolor),side[2],side[3]);
    216         }
    217       }
    218       svg.Add(base,dx+p+t,0,false,true);
    219       svg.Clean();
    220       this.SVGhandleSpace(svg);
    221       this.SVGhandleColor(svg);
    222       this.SVGsaveData(svg);
    223       return svg;
    224     },
    225     
    226     SVGxy: function (x,y) {return Math.floor(x)+","+Math.floor(y)}
    227     
    228   });
    229   
    230   MathJax.Hub.Startup.signal.Post("SVG menclose Ready");
    231   MathJax.Ajax.loadComplete(SVG.autoloadDir+"/menclose.js");
    232   
    233 });
    234