The R Project SVN R

Rev

Rev 526 | Rev 1009 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 526 Rev 581
Line 26... Line 26...
26
#ifdef max
26
#ifdef max
27
#undef max
27
#undef max
28
#endif
28
#endif
29
#ifdef Unix
29
#ifdef Unix
30
 
30
 
-
 
31
static DevDesc *mathDevice;
-
 
32
 
31
		/* return maximum of two doubles */
33
		/* return maximum of two doubles */
32
 
34
 
33
static double max(double x, double y)
35
static double max(double x, double y)
34
{
36
{
35
	if (x > y) return x;
37
	if (x > y) return x;
Line 199... Line 201...
199
	/* initialisation code for mathematical notation */
201
	/* initialisation code for mathematical notation */
200
 
202
 
201
static double ratioScale = 0.8;
203
static double ratioScale = 0.8;
202
static double scriptScale = 0.65;
204
static double scriptScale = 0.65;
203
static int ratioDepth = 0;
205
static int ratioDepth = 0;
204
static int metricUnit = 3;
206
static int metricUnit = INCHES;
205
 
207
 
206
static SEXP plusSymbol;
208
static SEXP plusSymbol;
207
static SEXP minusSymbol;
209
static SEXP minusSymbol;
208
static SEXP timesSymbol;
210
static SEXP timesSymbol;
209
static SEXP divideSymbol;
211
static SEXP divideSymbol;
Line 477... Line 479...
477
static float OperatorSpace[] = { 0.1, 0.15, 0.2, 0.6, 0.1 };
479
static float OperatorSpace[] = { 0.1, 0.15, 0.2, 0.6, 0.1 };
478
 
480
 
479
static double fontHeight()
481
static double fontHeight()
480
{
482
{
481
	double height, depth, width;
483
	double height, depth, width;
482
	GMetricInfo(0, &height, &depth, &width, metricUnit);
484
	GMetricInfo(0, &height, &depth, &width, metricUnit, mathDevice);
483
	return height + depth;
485
	return height + depth;
484
}
486
}
485
 
487
 
486
static double xHeight()
488
static double xHeight()
487
{
489
{
488
	int x = 'x';
490
	int x = 'x';
489
	double xheight, depth, width;
491
	double xheight, depth, width;
490
	GMetricInfo(x, &xheight, &depth, &width, metricUnit);
492
	GMetricInfo(x, &xheight, &depth, &width, metricUnit, mathDevice);
491
	return xheight;
493
	return xheight;
492
}
494
}
493
 
495
 
494
static double axisHeight()
496
static double axisHeight()
495
{
497
{
496
	int plus = '+';
498
	int plus = '+';
497
	double plusHeight, depth, width;
499
	double plusHeight, depth, width;
498
	GMetricInfo(plus, &plusHeight, &depth, &width, metricUnit);
500
	GMetricInfo(plus, &plusHeight, &depth, &width, metricUnit, mathDevice);
499
	return 0.5 * plusHeight;
501
	return 0.5 * plusHeight;
500
}
502
}
501
 
503
 
502
static double superscriptDrop()
504
static double superscriptDrop()
503
{
505
{
Line 565... Line 567...
565
 
567
 
566
static double radicalExWidth()
568
static double radicalExWidth()
567
{
569
{
568
	int radicalEx = 96;
570
	int radicalEx = 96;
569
	double height, depth, REWidth;
571
	double height, depth, REWidth;
570
	GMetricInfo(radicalEx, &height, &depth, &REWidth, metricUnit);
572
	GMetricInfo(radicalEx, &height, &depth, &REWidth, metricUnit, mathDevice);
571
	return REWidth;
573
	return REWidth;
572
}
574
}
573
 
575
 
574
static double superscriptShift(SEXP body, SEXP sup)
576
static double superscriptShift(SEXP body, SEXP sup)
575
{
577
{
576
	BBOX bodyBBox = elementBBox(body);
578
	BBOX bodyBBox = elementBBox(body);
577
	BBOX superscriptBBox;
579
	BBOX superscriptBBox;
578
	float cexSaved = GP->cex;
580
	float cexSaved = mathDevice->gp.cex;
579
	double temp1 = bboxHeight(bodyBBox) - superscriptDrop();
581
	double temp1 = bboxHeight(bodyBBox) - superscriptDrop();
580
	double temp2 = superscript();
582
	double temp2 = superscript();
581
	double temp3;
583
	double temp3;
582
 
584
 
583
	GP->cex = GP->cex * scriptScale;
585
	mathDevice->gp.cex = mathDevice->gp.cex * scriptScale;
584
	superscriptBBox = elementBBox(sup);
586
	superscriptBBox = elementBBox(sup);
585
	GP->cex = cexSaved;
587
	mathDevice->gp.cex = cexSaved;
586
	temp3 = bboxDepth(superscriptBBox) + 0.25 * xHeight();
588
	temp3 = bboxDepth(superscriptBBox) + 0.25 * xHeight();
587
 
589
 
588
	return max(temp1, max(temp2, temp3));
590
	return max(temp1, max(temp2, temp3));
589
}
591
}
590
 
592
 
591
static double subscriptShift(SEXP body, SEXP sub, int subOnly)
593
static double subscriptShift(SEXP body, SEXP sub, int subOnly)
592
{
594
{
593
	BBOX bodyBBox = elementBBox(body);
595
	BBOX bodyBBox = elementBBox(body);
594
	BBOX subscriptBBox;
596
	BBOX subscriptBBox;
595
	float cexSaved = GP->cex;
597
	float cexSaved = mathDevice->gp.cex;
596
	double temp1 = bboxDepth(bodyBBox) + subscriptDrop();
598
	double temp1 = bboxDepth(bodyBBox) + subscriptDrop();
597
	double temp2 = subscript();
599
	double temp2 = subscript();
598
	double temp3;
600
	double temp3;
599
 
601
 
600
	GP->cex = GP->cex * scriptScale;
602
	mathDevice->gp.cex = mathDevice->gp.cex * scriptScale;
601
	subscriptBBox = elementBBox(sub);
603
	subscriptBBox = elementBBox(sub);
602
	GP->cex = cexSaved;
604
	mathDevice->gp.cex = cexSaved;
603
	temp3 = bboxHeight(subscriptBBox) - (4 * xHeight() / 5);
605
	temp3 = bboxHeight(subscriptBBox) - (4 * xHeight() / 5);
604
 
606
 
605
	if (subOnly)
607
	if (subOnly)
606
		return max(temp1, max(temp2, temp3));
608
		return max(temp1, max(temp2, temp3));
607
	else
609
	else
Line 610... Line 612...
610
 
612
 
611
static void supsubShift(SEXP body, SEXP sup, SEXP sub,
613
static void supsubShift(SEXP body, SEXP sup, SEXP sub,
612
			double *supShift, double *subShift)
614
			double *supShift, double *subShift)
613
{
615
{
614
	BBOX superscriptBBox, subscriptBBox;
616
	BBOX superscriptBBox, subscriptBBox;
615
	float cexSaved = GP->cex;
617
	float cexSaved = mathDevice->gp.cex;
616
	double temp1, temp2;
618
	double temp1, temp2;
617
 
619
 
618
	GP->cex = GP->cex * scriptScale;
620
	mathDevice->gp.cex = mathDevice->gp.cex * scriptScale;
619
	superscriptBBox = elementBBox(sup);
621
	superscriptBBox = elementBBox(sup);
620
	subscriptBBox = elementBBox(sub);
622
	subscriptBBox = elementBBox(sub);
621
	GP->cex = cexSaved;
623
	mathDevice->gp.cex = cexSaved;
622
	*supShift = superscriptShift(body, sup);
624
	*supShift = superscriptShift(body, sup);
623
	*subShift = subscriptShift(body, sub, 0);
625
	*subShift = subscriptShift(body, sub, 0);
624
 
626
 
625
	temp1 = (*supShift - bboxDepth(superscriptBBox)) -
627
	temp1 = (*supShift - bboxDepth(superscriptBBox)) -
626
	    (bboxHeight(subscriptBBox) - *subShift);
628
	    (bboxHeight(subscriptBBox) - *subShift);
Line 656... Line 658...
656
}
658
}
657
 
659
 
658
static double numeratorVShift(SEXP num)
660
static double numeratorVShift(SEXP num)
659
{
661
{
660
	BBOX numBBox;
662
	BBOX numBBox;
661
	float cexSaved = GP->cex;
663
	float cexSaved = mathDevice->gp.cex;
662
	double theShift, theClearance, minClearance;
664
	double theShift, theClearance, minClearance;
663
 
665
 
664
	GP->cex = GP->cex * scriptScale;
666
	mathDevice->gp.cex = mathDevice->gp.cex * scriptScale;
665
	numBBox = elementBBox(num);
667
	numBBox = elementBBox(num);
666
	GP->cex = cexSaved;
668
	mathDevice->gp.cex = cexSaved;
667
 
669
 
668
	theShift = numeratorShift();
670
	theShift = numeratorShift();
669
	theClearance = numeratorShift() - bboxDepth(numBBox) -
671
	theClearance = numeratorShift() - bboxDepth(numBBox) -
670
	    (axisHeight() + 0.5 * lineWidth());
672
	    (axisHeight() + 0.5 * lineWidth());
671
	minClearance = 3 * lineWidth();
673
	minClearance = 3 * lineWidth();
Line 678... Line 680...
678
 
680
 
679
/* RATIO */
681
/* RATIO */
680
static double denominatorVShift(SEXP denom)
682
static double denominatorVShift(SEXP denom)
681
{
683
{
682
	BBOX denomBBox;
684
	BBOX denomBBox;
683
	float cexSaved = GP->cex;
685
	float cexSaved = mathDevice->gp.cex;
684
	double theShift, theClearance, minClearance;
686
	double theShift, theClearance, minClearance;
685
 
687
 
686
#ifdef OLD
688
#ifdef OLD
687
	GP->cex = GP->cex * scriptScale;
689
	mathDevice->gp.cex = mathDevice->gp.cex * scriptScale;
688
#else
690
#else
689
	GP->cex = GP->cex * ratioScale;
691
	mathDevice->gp.cex = mathDevice->gp.cex * ratioScale;
690
#endif
692
#endif
691
	denomBBox = elementBBox(denom);
693
	denomBBox = elementBBox(denom);
692
#ifdef OLD
694
#ifdef OLD
693
	GP->cex = cexSaved;
695
	mathDevice->gp.cex = cexSaved;
694
#else
696
#else
695
	GP->cex = cexSaved;
697
	mathDevice->gp.cex = cexSaved;
696
#endif
698
#endif
697
 
699
 
698
	theShift = denominatorShift();
700
	theShift = denominatorShift();
699
	theClearance = axisHeight() - 0.5 * lineWidth() -
701
	theClearance = axisHeight() - 0.5 * lineWidth() -
700
	    (bboxHeight(denomBBox) - denominatorShift());
702
	    (bboxHeight(denomBBox) - denominatorShift());
Line 709... Line 711...
709
/* RATIO */
711
/* RATIO */
710
static double fractionWidth(SEXP num, SEXP denom)
712
static double fractionWidth(SEXP num, SEXP denom)
711
{
713
{
712
	BBOX numBBox;
714
	BBOX numBBox;
713
	BBOX denomBBox;
715
	BBOX denomBBox;
714
	float cexSaved = GP->cex;
716
	float cexSaved = mathDevice->gp.cex;
715
	double temp1, temp2;
717
	double temp1, temp2;
716
 
718
 
717
#ifdef OLD
719
#ifdef OLD
718
	GP->cex = GP->cex * scriptScale;
720
	mathDevice->gp.cex = mathDevice->gp.cex * scriptScale;
719
#else
721
#else
720
	GP->cex = GP->cex * ratioScale;
722
	mathDevice->gp.cex = mathDevice->gp.cex * ratioScale;
721
#endif
723
#endif
722
	numBBox = elementBBox(num);
724
	numBBox = elementBBox(num);
723
	denomBBox = elementBBox(denom);
725
	denomBBox = elementBBox(denom);
724
#ifdef OLD
726
#ifdef OLD
725
	GP->cex = cexSaved;
727
	mathDevice->gp.cex = cexSaved;
726
#else
728
#else
727
	GP->cex = cexSaved;
729
	mathDevice->gp.cex = cexSaved;
728
#endif
730
#endif
729
	temp1 = bboxWidth(numBBox);
731
	temp1 = bboxWidth(numBBox);
730
	temp2 = bboxWidth(denomBBox);
732
	temp2 = bboxWidth(denomBBox);
731
 
733
 
732
	return max(temp1, temp2);
734
	return max(temp1, temp2);
Line 736... Line 738...
736
static void numdenomHShift(SEXP num, SEXP denom,
738
static void numdenomHShift(SEXP num, SEXP denom,
737
			   double *numShift, double *denomShift)
739
			   double *numShift, double *denomShift)
738
{
740
{
739
	BBOX numBBox;
741
	BBOX numBBox;
740
	BBOX denomBBox;
742
	BBOX denomBBox;
741
	float cexSaved = GP->cex;
743
	float cexSaved = mathDevice->gp.cex;
742
	double temp1, temp2;
744
	double temp1, temp2;
743
 
745
 
744
#ifdef OLD
746
#ifdef OLD
745
	GP->cex = GP->cex * scriptScale;
747
	mathDevice->gp.cex = mathDevice->gp.cex * scriptScale;
746
#else
748
#else
747
	GP->cex = GP->cex * ratioScale;
749
	mathDevice->gp.cex = mathDevice->gp.cex * ratioScale;
748
#endif
750
#endif
749
	numBBox = elementBBox(num);
751
	numBBox = elementBBox(num);
750
	denomBBox = elementBBox(denom);
752
	denomBBox = elementBBox(denom);
751
#ifdef OLD
753
#ifdef OLD
752
	GP->cex = cexSaved;
754
	mathDevice->gp.cex = cexSaved;
753
#else
755
#else
754
	GP->cex = cexSaved;
756
	mathDevice->gp.cex = cexSaved;
755
#endif
757
#endif
756
	temp1 = bboxWidth(numBBox);
758
	temp1 = bboxWidth(numBBox);
757
	temp2 = bboxWidth(denomBBox);
759
	temp2 = bboxWidth(denomBBox);
758
 
760
 
759
	if (temp1 > temp2) {
761
	if (temp1 > temp2) {
Line 912... Line 914...
912
}
914
}
913
 
915
 
914
static BBOX makeBBoxFromChar(int chr)
916
static BBOX makeBBoxFromChar(int chr)
915
{
917
{
916
	double height, depth, width;
918
	double height, depth, width;
917
	GMetricInfo(chr, &height, &depth, &width, metricUnit);
919
	GMetricInfo(chr, &height, &depth, &width, metricUnit, mathDevice);
918
	return makeBBox(height, depth, width);
920
	return makeBBox(height, depth, width);
919
}
921
}
920
 
922
 
921
static BBOX shiftBBox(BBOX bbox, double shiftV)
923
static BBOX shiftBBox(BBOX bbox, double shiftV)
922
{
924
{
Line 948... Line 950...
948
static double currentAngle;
950
static double currentAngle;
949
static double cosAngle;
951
static double cosAngle;
950
static double sinAngle;
952
static double sinAngle;
951
 
953
 
952
		/* 
954
		/* 
953
		   // convert currentX and currentY from inches and 0 angle
955
		   // convert currentX and currentY from 0 angle
954
		   // to figure units and currentAngle
956
		   // to and currentAngle
955
		 */
957
		 */
956
static double convertedX()
958
static double convertedX()
957
{
959
{
958
	double rotatedX = referenceX +
960
	double rotatedX = referenceX +
959
	(currentX - referenceX) * cosAngle -
961
	(currentX - referenceX) * cosAngle -
960
	(currentY - referenceY) * sinAngle;
962
	(currentY - referenceY) * sinAngle;
961
	return xInchtoFig(rotatedX);
963
	return rotatedX;
962
}
964
}
963
 
965
 
964
static double convertedY()
966
static double convertedY()
965
{
967
{
966
	double rotatedY = referenceY +
968
	double rotatedY = referenceY +
967
	(currentY - referenceY) * cosAngle +
969
	(currentY - referenceY) * cosAngle +
968
	(currentX - referenceX) * sinAngle;
970
	(currentX - referenceX) * sinAngle;
969
	return yInchtoFig(rotatedY);
971
	return rotatedY;
970
}
972
}
971
 
973
 
972
static void moveAcross(double xamount)
974
static void moveAcross(double xamount)
973
{
975
{
974
	currentX += xamount;
976
	currentX += xamount;
Line 991... Line 993...
991
	/* been converted to ascii are in the symbol font */
993
	/* been converted to ascii are in the symbol font */
992
 
994
 
993
static BBOX asciiBBox(int ascii)
995
static BBOX asciiBBox(int ascii)
994
{
996
{
995
	if ((ascii == hatAscii()) || (ascii == tildeAscii()))
997
	if ((ascii == hatAscii()) || (ascii == tildeAscii()))
996
		GP->font = 1;
998
		mathDevice->gp.font = 1;
997
	else
999
	else
998
		GP->font = 5;
1000
		mathDevice->gp.font = 5;
999
	return makeBBoxFromChar(ascii);
1001
	return makeBBoxFromChar(ascii);
1000
}
1002
}
1001
 
1003
 
1002
static void drawAscii(int ascii)
1004
static void drawAscii(int ascii)
1003
{
1005
{
1004
	char asciiStr[2];
1006
	char asciiStr[2];
1005
 
1007
 
1006
	if ((ascii == hatAscii()) || (ascii == tildeAscii()))
1008
	if ((ascii == hatAscii()) || (ascii == tildeAscii()))
1007
		GP->font = 1;
1009
		mathDevice->gp.font = 1;
1008
	else
1010
	else
1009
		GP->font = 5;
1011
		mathDevice->gp.font = 5;
1010
	asciiStr[0] = ascii;
1012
	asciiStr[0] = ascii;
1011
	asciiStr[1] = '\0';
1013
	asciiStr[1] = '\0';
1012
	GText(convertedX(), convertedY(), asciiStr, 0.0, 0.0, currentAngle);
1014
	GText(convertedX(), convertedY(), INCHES, asciiStr, 
-
 
1015
	      0.0, 0.0, currentAngle, mathDevice);
1013
	moveAcross(GStrWidth(asciiStr, metricUnit));
1016
	moveAcross(GStrWidth(asciiStr, metricUnit, mathDevice));
1014
}
1017
}
1015
 
1018
 
1016
/* code for character atoms */
1019
/* code for character atoms */
1017
 
1020
 
1018
static BBOX charBBox(char *str, SEXP expr)
1021
static BBOX charBBox(char *str, SEXP expr)
1019
{
1022
{
1020
	BBOX resultBBox = nullBBox();
1023
	BBOX resultBBox = nullBBox();
1021
	int i;
1024
	int i;
1022
 
1025
 
1023
	GP->font = atomFontFace(expr);
1026
	mathDevice->gp.font = atomFontFace(expr);
1024
	for (i = 0; i < strlen(str); i++)
1027
	for (i = 0; i < strlen(str); i++)
1025
		resultBBox = combineBBoxes(resultBBox, makeBBoxFromChar(str[i]));
1028
		resultBBox = combineBBoxes(resultBBox, makeBBoxFromChar(str[i]));
1026
 
1029
 
1027
	return resultBBox;
1030
	return resultBBox;
1028
}
1031
}
1029
 
1032
 
1030
static void drawChar(char *str, SEXP expr)
1033
static void drawChar(char *str, SEXP expr)
1031
{
1034
{
1032
	GP->font = atomFontFace(expr);
1035
	mathDevice->gp.font = atomFontFace(expr);
1033
	GText(convertedX(), convertedY(), str, 0.0, 0.0, currentAngle);
1036
	GText(convertedX(), convertedY(), INCHES, str, 
-
 
1037
	      0.0, 0.0, currentAngle, mathDevice);
1034
	moveAcross(GStrWidth(str, metricUnit));
1038
	moveAcross(GStrWidth(str, metricUnit, mathDevice));
1035
}
1039
}
1036
 
1040
 
1037
/* code for symbol atoms */
1041
/* code for symbol atoms */
1038
 
1042
 
1039
static BBOX symbolBBox(SEXP expr)
1043
static BBOX symbolBBox(SEXP expr)
Line 1151... Line 1155...
1151
 
1155
 
1152
static int cexGap = 1;
1156
static int cexGap = 1;
1153
 
1157
 
1154
static void setGapCEX()
1158
static void setGapCEX()
1155
{
1159
{
1156
  cexGap = GP->cex;
1160
  cexGap = mathDevice->gp.cex;
1157
}
1161
}
1158
 
1162
 
1159
static BBOX gapBBox(double gap)
1163
static BBOX gapBBox(double gap)
1160
{
1164
{
1161
  double cexSaved = GP->cex;
1165
  double cexSaved = mathDevice->gp.cex;
1162
  BBOX theBBox;
1166
  BBOX theBBox;
1163
 
1167
 
1164
  GP->cex = cexGap;
1168
  mathDevice->gp.cex = cexGap;
1165
  theBBox = makeBBox(0, 0, gap * fontHeight());
1169
  theBBox = makeBBox(0, 0, gap * fontHeight());
1166
  GP->cex = cexSaved;
1170
  mathDevice->gp.cex = cexSaved;
1167
 
1171
 
1168
  return theBBox;
1172
  return theBBox;
1169
}
1173
}
1170
 
1174
 
1171
static BBOX smallgapBBox(double gap)
1175
static BBOX smallgapBBox(double gap)
1172
{
1176
{
1173
  double cexSaved = GP->cex;
1177
  double cexSaved = mathDevice->gp.cex;
1174
  BBOX theBBox;
1178
  BBOX theBBox;
1175
 
1179
 
1176
  GP->cex = cexGap;
1180
  mathDevice->gp.cex = cexGap;
1177
  theBBox = makeBBox(0, 0, 0.5 * gap * fontHeight());
1181
  theBBox = makeBBox(0, 0, 0.5 * gap * fontHeight());
1178
  GP->cex = cexSaved;
1182
  mathDevice->gp.cex = cexSaved;
1179
 
1183
 
1180
  return theBBox;
1184
  return theBBox;
1181
}
1185
}
1182
 
1186
 
1183
static void drawGap(double gap)
1187
static void drawGap(double gap)
1184
{
1188
{
1185
  double cexSaved = GP->cex;
1189
  double cexSaved = mathDevice->gp.cex;
1186
 
1190
 
1187
  GP->cex = cexGap;
1191
  mathDevice->gp.cex = cexGap;
1188
  moveAcross(gap * fontHeight());
1192
  moveAcross(gap * fontHeight());
1189
  GP->cex = cexSaved;
1193
  mathDevice->gp.cex = cexSaved;
1190
}
1194
}
1191
 
1195
 
1192
static void drawSmallGap(double gap)
1196
static void drawSmallGap(double gap)
1193
{
1197
{
1194
  double cexSaved = GP->cex;
1198
  double cexSaved = mathDevice->gp.cex;
1195
 
1199
 
1196
  GP->cex = cexGap;
1200
  mathDevice->gp.cex = cexGap;
1197
  moveAcross(0.5 * gap * fontHeight());
1201
  moveAcross(0.5 * gap * fontHeight());
1198
  GP->cex = cexSaved;
1202
  mathDevice->gp.cex = cexSaved;
1199
}
1203
}
1200
 
1204
 
1201
/* code for binary operator (+, -, *, /) expressions */
1205
/* code for binary operator (+, -, *, /) expressions */
1202
 
1206
 
1203
/* NOTE that gaps are specified as proportions of the current font height */
1207
/* NOTE that gaps are specified as proportions of the current font height */
Line 1280... Line 1284...
1280
static BBOX supsubBBox(SEXP body, SEXP superscript, SEXP subscript);
1284
static BBOX supsubBBox(SEXP body, SEXP superscript, SEXP subscript);
1281
 
1285
 
1282
static BBOX superscriptBBox(SEXP superscript)
1286
static BBOX superscriptBBox(SEXP superscript)
1283
{
1287
{
1284
	BBOX result;
1288
	BBOX result;
1285
	float cexSaved = GP->cex;
1289
	float cexSaved = mathDevice->gp.cex;
1286
 
1290
 
1287
	GP->cex = GP->cex * scriptScale;
1291
	mathDevice->gp.cex = mathDevice->gp.cex * scriptScale;
1288
	result = elementBBox(superscript);
1292
	result = elementBBox(superscript);
1289
	GP->cex = cexSaved;
1293
	mathDevice->gp.cex = cexSaved;
1290
 
1294
 
1291
	return result;
1295
	return result;
1292
}
1296
}
1293
 
1297
 
1294
static BBOX supBBox(SEXP expr)
1298
static BBOX supBBox(SEXP expr)
Line 1313... Line 1317...
1313
}
1317
}
1314
 
1318
 
1315
static BBOX subscriptBBox(SEXP subscript)
1319
static BBOX subscriptBBox(SEXP subscript)
1316
{
1320
{
1317
	BBOX result;
1321
	BBOX result;
1318
	float cexSaved = GP->cex;
1322
	float cexSaved = mathDevice->gp.cex;
1319
 
1323
 
1320
	GP->cex = GP->cex * scriptScale;
1324
	mathDevice->gp.cex = mathDevice->gp.cex * scriptScale;
1321
	result = elementBBox(subscript);
1325
	result = elementBBox(subscript);
1322
	GP->cex = cexSaved;
1326
	mathDevice->gp.cex = cexSaved;
1323
 
1327
 
1324
	return result;
1328
	return result;
1325
}
1329
}
1326
 
1330
 
1327
static BBOX subBBox(SEXP expr)
1331
static BBOX subBBox(SEXP expr)
Line 1348... Line 1352...
1348
		   shiftBBox(subscriptBBox(subscript), subShift)));
1352
		   shiftBBox(subscriptBBox(subscript), subShift)));
1349
}
1353
}
1350
 
1354
 
1351
static void drawScriptElement(SEXP expr)
1355
static void drawScriptElement(SEXP expr)
1352
{
1356
{
1353
	float cexSaved = GP->cex;
1357
	float cexSaved = mathDevice->gp.cex;
1354
 
1358
 
1355
	GP->cex = GP->cex * scriptScale;
1359
	mathDevice->gp.cex = mathDevice->gp.cex * scriptScale;
1356
	drawElement(expr);
1360
	drawElement(expr);
1357
	GP->cex = cexSaved;
1361
	mathDevice->gp.cex = cexSaved;
1358
}
1362
}
1359
 
1363
 
1360
static void drawSupSub(SEXP body, SEXP superscript, SEXP subscript);
1364
static void drawSupSub(SEXP body, SEXP superscript, SEXP subscript);
1361
 
1365
 
1362
static void drawSuper(SEXP expr)
1366
static void drawSuper(SEXP expr)
Line 1454... Line 1458...
1454
{
1458
{
1455
	BBOX bodyBBox = elementBBox(body);
1459
	BBOX bodyBBox = elementBBox(body);
1456
	double width = bboxWidth(bodyBBox);
1460
	double width = bboxWidth(bodyBBox);
1457
	double savedX = currentX;
1461
	double savedX = currentX;
1458
	double savedY = currentY;
1462
	double savedY = currentY;
-
 
1463
	double x[3], y[3];
1459
 
1464
 
1460
	moveUp(bboxHeight(bodyBBox) + customAccentGap());
1465
	moveUp(bboxHeight(bodyBBox) + customAccentGap());
1461
	GStartPath();
-
 
1462
	GMoveTo(convertedX(), convertedY());
1466
	x[0] = convertedX(); y[0] = convertedY();
1463
	moveUp(customHatHeight());
1467
	moveUp(customHatHeight());
1464
	moveAcross(width / 2);
1468
	moveAcross(width / 2);
1465
	GLineTo(convertedX(), convertedY());
1469
	x[1] = convertedX(); y[1] = convertedY();
1466
	moveUp(-customHatHeight());
1470
	moveUp(-customHatHeight());
1467
	moveAcross(width / 2);
1471
	moveAcross(width / 2);
1468
	GLineTo(convertedX(), convertedY());
1472
	x[2] = convertedX(); y[2] = convertedY();
1469
	GEndPath();
1473
	GPolyline(3, x, y, INCHES, mathDevice);
1470
	moveTo(savedX, savedY);
1474
	moveTo(savedX, savedY);
1471
	drawElement(body);
1475
	drawElement(body);
1472
}
1476
}
1473
 
1477
 
1474
static void drawBar(SEXP body)
1478
static void drawBar(SEXP body)
1475
{
1479
{
1476
	BBOX bodyBBox = elementBBox(body);
1480
	BBOX bodyBBox = elementBBox(body);
1477
	double savedX = currentX;
1481
	double savedX = currentX;
1478
	double savedY = currentY;
1482
	double savedY = currentY;
-
 
1483
	double x[2], y[2];
1479
 
1484
 
1480
	moveUp(bboxHeight(bodyBBox) + customAccentGap());
1485
	moveUp(bboxHeight(bodyBBox) + customAccentGap());
1481
	GStartPath();
-
 
1482
	GMoveTo(convertedX(), convertedY());
1486
	x[0] = convertedX(); y[0] = convertedY();
1483
	moveAcross(bboxWidth(bodyBBox));
1487
	moveAcross(bboxWidth(bodyBBox));
1484
	GLineTo(convertedX(), convertedY());
1488
	x[1] = convertedX(); y[1] = convertedY();
1485
	GEndPath();
1489
	GPolyline(2, x, y, INCHES, mathDevice);
1486
	moveTo(savedX, savedY);
1490
	moveTo(savedX, savedY);
1487
	drawElement(body);
1491
	drawElement(body);
1488
}
1492
}
1489
 
1493
 
1490
static void drawAccent(SEXP expr)
1494
static void drawAccent(SEXP expr)
Line 1513... Line 1517...
1513
{
1517
{
1514
	SEXP numerator = CADR(expr);
1518
	SEXP numerator = CADR(expr);
1515
	SEXP denominator = CADDR(expr);
1519
	SEXP denominator = CADDR(expr);
1516
	BBOX numBBox, denomBBox;
1520
	BBOX numBBox, denomBBox;
1517
	double numHShift, denomHShift;
1521
	double numHShift, denomHShift;
1518
	float cexSaved = GP->cex;
1522
	float cexSaved = mathDevice->gp.cex;
1519
 
1523
 
1520
#ifdef OLD
1524
#ifdef OLD
1521
	GP->cex = GP->cex * scriptScale;
1525
	mathDevice->gp.cex = mathDevice->gp.cex * scriptScale;
1522
#else
1526
#else
1523
	GP->cex = GP->cex * ratioScale;
1527
	mathDevice->gp.cex = mathDevice->gp.cex * ratioScale;
1524
#endif
1528
#endif
1525
	numBBox = elementBBox(numerator);
1529
	numBBox = elementBBox(numerator);
1526
	denomBBox = elementBBox(denominator);
1530
	denomBBox = elementBBox(denominator);
1527
#ifdef OLD
1531
#ifdef OLD
1528
	GP->cex = cexSaved;
1532
	mathDevice->gp.cex = cexSaved;
1529
#else
1533
#else
1530
	GP->cex = cexSaved;
1534
	mathDevice->gp.cex = cexSaved;
1531
#endif
1535
#endif
1532
	numdenomHShift(numerator, denominator, &numHShift, &denomHShift);
1536
	numdenomHShift(numerator, denominator, &numHShift, &denomHShift);
1533
 
1537
 
1534
	return combineAlignedBBoxes(
1538
	return combineAlignedBBoxes(
1535
	     shiftBBox(combineBBoxes(makeBBox(numHShift, 0, 0), numBBox),
1539
	     shiftBBox(combineBBoxes(makeBBox(numHShift, 0, 0), numBBox),
Line 1538... Line 1542...
1538
		   -denominatorVShift(denominator)));
1542
		   -denominatorVShift(denominator)));
1539
}
1543
}
1540
 
1544
 
1541
static void drawRatioElement(SEXP expr)
1545
static void drawRatioElement(SEXP expr)
1542
{
1546
{
1543
	float cexSaved = GP->cex;
1547
	float cexSaved = mathDevice->gp.cex;
1544
	GP->cex = GP->cex * ratioScale;
1548
	mathDevice->gp.cex = mathDevice->gp.cex * ratioScale;
1545
	drawElement(expr);
1549
	drawElement(expr);
1546
	GP->cex = cexSaved;
1550
	mathDevice->gp.cex = cexSaved;
1547
}
1551
}
1548
 
1552
 
1549
static void drawFraction(SEXP expr)
1553
static void drawFraction(SEXP expr)
1550
{
1554
{
1551
	SEXP numerator = CADR(expr);
1555
	SEXP numerator = CADR(expr);
1552
	SEXP denominator = CADDR(expr);
1556
	SEXP denominator = CADDR(expr);
1553
	double savedX = currentX;
1557
	double savedX = currentX;
1554
	double savedY = currentY;
1558
	double savedY = currentY;
1555
	double fWidth = fractionWidth(numerator, denominator);
1559
	double fWidth = fractionWidth(numerator, denominator);
1556
	double numHShift, denomHShift;
1560
	double numHShift, denomHShift;
-
 
1561
	double x[2], y[2];
1557
 
1562
 
1558
	numdenomHShift(numerator, denominator, &numHShift, &denomHShift);
1563
	numdenomHShift(numerator, denominator, &numHShift, &denomHShift);
1559
	moveAcross(numHShift);
1564
	moveAcross(numHShift);
1560
	moveUp(numeratorVShift(numerator));
1565
	moveUp(numeratorVShift(numerator));
1561
#ifdef OLD
1566
#ifdef OLD
Line 1563... Line 1568...
1563
#else
1568
#else
1564
	drawRatioElement(numerator);
1569
	drawRatioElement(numerator);
1565
#endif
1570
#endif
1566
	moveTo(savedX, savedY);
1571
	moveTo(savedX, savedY);
1567
	moveUp(axisHeight());
1572
	moveUp(axisHeight());
1568
	GStartPath();
-
 
1569
	GMoveTo(convertedX(), convertedY());
1573
	x[0] = convertedX(); y[0] = convertedY();
1570
	moveAcross(fWidth);
1574
	moveAcross(fWidth);
1571
	GLineTo(convertedX(), convertedY());
1575
	x[1] = convertedX(); y[1] = convertedY();
1572
	GEndPath();
1576
	GPolyline(2, x, y, INCHES, mathDevice);
1573
	moveTo(savedX, savedY);
1577
	moveTo(savedX, savedY);
1574
	moveAcross(denomHShift);
1578
	moveAcross(denomHShift);
1575
	moveUp(-denominatorVShift(denominator));
1579
	moveUp(-denominatorVShift(denominator));
1576
#ifdef OLD
1580
#ifdef OLD
1577
	drawScriptElement(denominator);
1581
	drawScriptElement(denominator);
Line 1628... Line 1632...
1628
 
1632
 
1629
static useRelGap = 1;
1633
static useRelGap = 1;
1630
  
1634
  
1631
static BBOX operatorLimitBBox(SEXP limit)
1635
static BBOX operatorLimitBBox(SEXP limit)
1632
{
1636
{
1633
  float cexSaved = GP->cex;
1637
  float cexSaved = mathDevice->gp.cex;
1634
  BBOX limitBBox;
1638
  BBOX limitBBox;
1635
 
1639
 
1636
  GP->cex = GP->cex * scriptScale;
1640
  mathDevice->gp.cex = mathDevice->gp.cex * scriptScale;
1637
  useRelGap = 0;
1641
  useRelGap = 0;
1638
  limitBBox = elementBBox(limit);
1642
  limitBBox = elementBBox(limit);
1639
  useRelGap = 1;
1643
  useRelGap = 1;
1640
  GP->cex = cexSaved;
1644
  mathDevice->gp.cex = cexSaved;
1641
 
1645
 
1642
  return limitBBox;
1646
  return limitBBox;
1643
}
1647
}
1644
 
1648
 
1645
static BBOX operatorBBox(SEXP expr)
1649
static BBOX operatorBBox(SEXP expr)
Line 1789... Line 1793...
1789
	double depth = bboxDepth(bodyBBox);
1793
	double depth = bboxDepth(bodyBBox);
1790
	double width = bboxWidth(bodyBBox);
1794
	double width = bboxWidth(bodyBBox);
1791
	double twiddleHeight = (height - depth) / 2;
1795
	double twiddleHeight = (height - depth) / 2;
1792
	double savedX = currentX;
1796
	double savedX = currentX;
1793
	double savedY = currentY;
1797
	double savedY = currentY;
-
 
1798
	double x[5], y[5];
1794
 
1799
 
1795
	moveUp(0.8 * twiddleHeight);
1800
	moveUp(0.8 * twiddleHeight);
1796
	GStartPath();
-
 
1797
	GMoveTo(convertedX(), convertedY());
1801
	x[0] = convertedX(); y[0] = convertedY();
1798
	moveUp(0.2 * twiddleHeight);
1802
	moveUp(0.2 * twiddleHeight);
1799
	moveAcross(0.3 * customRadicalWidth());
1803
	moveAcross(0.3 * customRadicalWidth());
1800
	GLineTo(convertedX(), convertedY());
1804
	x[1] = convertedX(); y[1] = convertedY();
1801
	moveUp(-(twiddleHeight + depth));
1805
	moveUp(-(twiddleHeight + depth));
1802
	moveAcross(0.3 * customRadicalWidth());
1806
	moveAcross(0.3 * customRadicalWidth());
1803
	GLineTo(convertedX(), convertedY());
1807
	x[2] = convertedX(); y[2] = convertedY();
1804
	moveUp(depth + height + customRadicalGap());
1808
	moveUp(depth + height + customRadicalGap());
1805
	moveAcross(0.4 * customRadicalWidth());
1809
	moveAcross(0.4 * customRadicalWidth());
1806
	GLineTo(convertedX(), convertedY());
1810
	x[3] = convertedX(); y[3] = convertedY();
1807
	moveAcross(customRadicalSpace() + width);
1811
	moveAcross(customRadicalSpace() + width);
1808
	GLineTo(convertedX(), convertedY());
1812
	x[4] = convertedX(); y[4] = convertedY();
1809
	GEndPath();
1813
	GPolyline(5, x, y, INCHES, mathDevice);
1810
	moveTo(savedX, savedY);
1814
	moveTo(savedX, savedY);
1811
	moveAcross(customRadicalWidth() + customRadicalSpace());
1815
	moveAcross(customRadicalWidth() + customRadicalSpace());
1812
	drawElement(body);
1816
	drawElement(body);
1813
}
1817
}
1814
 
1818
 
Line 1832... Line 1836...
1832
{
1836
{
1833
	SEXP body = CADR(expr);
1837
	SEXP body = CADR(expr);
1834
	BBOX bodyBBox = elementBBox(expr);
1838
	BBOX bodyBBox = elementBBox(expr);
1835
	double height = bboxHeight(bodyBBox);
1839
	double height = bboxHeight(bodyBBox);
1836
	double depth = bboxDepth(bodyBBox);
1840
	double depth = bboxDepth(bodyBBox);
-
 
1841
	double width = bboxWidth(bodyBBox);
-
 
1842
	double savedX = currentX;
-
 
1843
	double savedY = currentY;
-
 
1844
	double x[2], y[2];
1837
 
1845
 
1838
	moveUp(-depth);
1846
	moveUp(-depth);
1839
	GStartPath();
-
 
1840
	GMoveTo(convertedX(), convertedY());
1847
	x[0] = convertedX(); y[0] = convertedY();
1841
	moveUp(depth + height);
1848
	moveUp(depth + height);
1842
	GLineTo(convertedX(), convertedY());
1849
	x[1] = convertedX(); y[1] = convertedY();
-
 
1850
	GPolyline(2, x, y, INCHES, mathDevice);
1843
	moveUp(-height);
1851
	moveUp(-height);
1844
	moveAcross(absSpace());
1852
	moveAcross(absSpace());
1845
	drawElement(body);
1853
	drawElement(body);
1846
	moveAcross(absSpace());
1854
	moveAcross(absSpace());
1847
	moveUp(-depth);
1855
	moveUp(-depth);
1848
	GMoveTo(convertedX(), convertedY());
1856
	x[0] = convertedX(); y[0] = convertedY();
1849
	moveUp(depth + height);
1857
	moveUp(depth + height);
1850
	GLineTo(convertedX(), convertedY());
1858
	x[1] = convertedX(); y[1] = convertedY();
1851
	GEndPath();
1859
	GPolyline(2, x, y, INCHES, mathDevice);
1852
	moveUp(-height);
1860
	moveUp(-height);
1853
}
1861
}
1854
 
1862
 
1855
/* code for general expressions with no special meaning in */
1863
/* code for general expressions with no special meaning in */
1856
/* mathematical notation syntax (e.g., f(x)) */
1864
/* mathematical notation syntax (e.g., f(x)) */
Line 2196... Line 2204...
2196
		drawAtom(expr);
2204
		drawAtom(expr);
2197
}
2205
}
2198
 
2206
 
2199
        /* calculate width of expression */
2207
        /* calculate width of expression */
2200
        /* BBOXes are in INCHES (see metricUnit) */
2208
        /* BBOXes are in INCHES (see metricUnit) */
2201
double GExpressionWidth(SEXP expr, int units)
2209
double GExpressionWidth(SEXP expr, int units, DevDesc *dd)
2202
{
2210
{
2203
        BBOX exprBBox = elementBBox(expr);
2211
        BBOX exprBBox = elementBBox(expr);
2204
        double w  = exprBBox.width;
2212
        double w  = exprBBox.width;
2205
        switch(units) {
2213
	if (units == INCHES)
2206
                case 1: /* user == world */
-
 
2207
                        w = ((exprBBox.width / GP->ipr[0]) / GP->fig2dev.bx) / GP->win2fig.bx;
-
 
2208
                        break;
-
 
2209
                case 2: /* figure */
-
 
2210
                        w = (exprBBox.width / GP->ipr[0]) / GP->fig2dev.bx;
-
 
2211
                        break;
-
 
2212
                case 3: /* inches */
-
 
2213
                        w = exprBBox.width;
-
 
2214
                        break;
-
 
2215
                case 4: /* rasters */
-
 
2216
                        w = exprBBox.width / GP->ipr[0];
-
 
2217
                        break;
2214
		return w;
2218
        }
2215
	else 
2219
        return w;
2216
		return GConvertXUnits(w, INCHES, units, dd);
2220
}
2217
}
2221
 
2218
 
2222
#define ABS(a)  ((a)>=0 ? (a) : -(a))
2219
#define ABS(a)  ((a)>=0 ? (a) : -(a))
2223
 
2220
 
2224
double GExpressionHeight(SEXP expr, int units)
2221
double GExpressionHeight(SEXP expr, int units, DevDesc *dd)
2225
{
2222
{
2226
        BBOX exprBBox = elementBBox(expr);
2223
        BBOX exprBBox = elementBBox(expr);
2227
        double h = exprBBox.height + exprBBox.depth;
2224
        double h = exprBBox.height + exprBBox.depth;
2228
        switch(units) {
2225
	if (units == INCHES)
2229
                case 1: /* user == world */
-
 
2230
                        h = ((h / GP->ipr[1]) / ABS(GP->fig2dev.by)) / GP->win2fig.by;
-
 
2231
                        break;
2226
		return h;
2232
                case 2: /* figure */
-
 
2233
                        h = (h / GP->ipr[1]) / ABS(GP->fig2dev.by);
-
 
2234
                        break;
-
 
2235
                case 3: /* inches */
-
 
2236
                        break;
-
 
2237
                case 4: /* rasters */
-
 
2238
                        h = h / GP->ipr[1];
-
 
2239
                        break;
-
 
2240
        }
2227
	else
2241
        return h;
2228
		return GConvertYUnits(h, INCHES, units, dd);
2242
}
2229
}
2243
 
2230
 
2244
		/* functions forming the API */
2231
		/* functions forming the API */
2245
 
2232
 
2246
void GMathText(double x, double y, SEXP expr, double xc, double yc, double rot)
2233
void GMathText(double x, double y, int coords, SEXP expr, 
-
 
2234
	       double xc, double yc, double rot, DevDesc *dd)
2247
{
2235
{
2248
	BBOX expressionBBox;
2236
	BBOX expressionBBox;
2249
 
2237
 
-
 
2238
	mathDevice = dd;
-
 
2239
 
2250
	initFormulaSymbols();
2240
	initFormulaSymbols();
2251
	expressionBBox = elementBBox(expr);
2241
	expressionBBox = elementBBox(expr);
2252
 
2242
 
2253
	/* NOTE that x and y are in Figure coordinates */
-
 
2254
 
-
 
2255
	referenceX = xFigtoInch(x);
2243
	referenceX = x;
2256
	referenceY = yFigtoInch(y);
2244
	referenceY = y;
-
 
2245
	GConvert(&referenceX, &referenceY, coords, INCHES, dd);
2257
 
2246
 
2258
	currentX = referenceX - xc * bboxWidth(expressionBBox);
2247
	currentX = referenceX - xc * bboxWidth(expressionBBox);
2259
	currentY = referenceY - yc * bboxHeight(expressionBBox);
2248
	currentY = referenceY - yc * bboxHeight(expressionBBox);
2260
	currentAngle = rot;
2249
	currentAngle = rot;
2261
	cosAngle = cos(rot / 90 * half_pi);
2250
	cosAngle = cos(rot / 90 * half_pi);
2262
	sinAngle = sin(rot / 90 * half_pi);
2251
	sinAngle = sin(rot / 90 * half_pi);
2263
	drawElement(expr);
2252
	drawElement(expr);
2264
}
2253
}
2265
 
2254
 
2266
 
2255
 
2267
#define XINVFMAP(x) ((x - GP->fig2dev.ax)/GP->fig2dev.bx)
-
 
2268
#define YINVFMAP(y) ((y - GP->fig2dev.ay)/GP->fig2dev.by)
-
 
2269
 
-
 
2270
void GMMathText(SEXP str, int side, double line, int outer, double at, int las)
2256
void GMMathText(SEXP str, int side, double line, int outer, double at, int las,
-
 
2257
		DevDesc *dd)
2271
{
2258
{
-
 
2259
	int coords;
2272
	double a, x, y, xadj, yadj;
2260
	double a, xadj, yadj;
-
 
2261
 
-
 
2262
	mathDevice = dd;
2273
 
2263
 
2274
	if (outer) {
2264
	if (outer) {
2275
		switch (side) {
2265
		switch (side) {
2276
		case 1:
2266
		case 1:
2277
			x = at;
2267
			line = line + 1;
2278
			y = yChartoNDC(GP->cexbase * GP->mex * (GP->oma[0] - line + 1));
-
 
2279
			x = DP->inner2dev.ax + DP->inner2dev.bx * x;
-
 
2280
			y = DP->ndc2dev.ay + DP->ndc2dev.by * y;
2268
			coords = MAR1;
2281
			a = 0.0;
2269
			a = 0.0;
2282
			xadj = GP->adj;
2270
			xadj = mathDevice->gp.adj;
2283
			yadj = 0.0;
2271
			yadj = 0.0;
2284
			break;
2272
			break;
2285
		case 2:
2273
		case 2:
2286
			x = xChartoNDC(GP->cexbase * GP->mex * (GP->oma[1] - line));
-
 
2287
			y = at;
2274
			coords = MAR2;
2288
			x = DP->ndc2dev.ax + DP->ndc2dev.bx * x;
-
 
2289
			y = DP->inner2dev.ay + DP->inner2dev.by * y;
-
 
2290
			a = 90.0;
2275
			a = 90.0;
2291
			xadj = GP->adj;
2276
			xadj = mathDevice->gp.adj;
2292
			yadj = 0.0;
2277
			yadj = 0.0;
2293
			break;
2278
			break;
2294
		case 3:
2279
		case 3:
2295
			x = at;
2280
			coords = MAR3;
2296
			y = 1.0 - yChartoNDC(GP->cexbase * GP->mex * (GP->oma[2] - line));
-
 
2297
			x = DP->inner2dev.ax + DP->inner2dev.bx * x;
-
 
2298
			y = DP->ndc2dev.ay + DP->ndc2dev.by * y;
-
 
2299
			a = 0.0;
2281
			a = 0.0;
2300
			xadj = GP->adj;
2282
			xadj = mathDevice->gp.adj;
2301
			yadj = 0.0;
2283
			yadj = 0.0;
2302
			break;
2284
			break;
2303
		case 4:
2285
		case 4:
2304
			x = 1.0 - xChartoNDC(GP->cexbase * GP->mex * (GP->oma[3] - line));
-
 
2305
			y = at;
2286
			line = line + 1;
2306
			x = DP->ndc2dev.ax + DP->ndc2dev.bx * x;
2287
			coords = MAR4;
2307
			y = DP->inner2dev.ay + DP->inner2dev.by * y;
-
 
2308
			a = 90.0;
2288
			a = 90.0;
2309
			xadj = GP->adj;
2289
			xadj = mathDevice->gp.adj;
2310
			yadj = 0.0;
2290
			yadj = 0.0;
2311
			break;
2291
			break;
2312
		}
2292
		}
2313
		x = XINVFMAP(x);
-
 
2314
		y = YINVFMAP(y);
-
 
2315
		GMathText(x, y, str, xadj, yadj, a);
2293
		GMathText(at, line, coords, str, xadj, yadj, a, dd);
2316
	}
2294
	}
2317
	else {
2295
	else {
2318
		switch (side) {
2296
		switch (side) {
2319
		case 1:
2297
		case 1:
2320
			if (las == 2) {
2298
			if (las == 2) {
2321
				y = GP->plt[2] - yInchtoFig(yChartoInch(GP->cexbase * GP->mex * (line + GP->yLineBias)));
2299
				at = at - GConvertXUnits(dd->gp.yLineBias,
-
 
2300
							 LINES, USER, dd);
2322
				x = XMAP(at) - xInchtoFig(xChartoInch(GP->cexbase * GP->mex * GP->yLineBias));
2301
				line = line + dd->gp.yLineBias;
2323
				a = 90.0;
2302
				a = 90.0;
2324
				xadj = 1.0;
2303
				xadj = 1.0;
2325
				yadj = 0.5;
2304
				yadj = 0.5;
2326
			}
2305
			}
2327
			else {
2306
			else {
2328
				y = GP->plt[2] - yInchtoFig(yChartoInch(GP->cexbase * GP->mex * (line + 1 - GP->yLineBias)));
2307
				line = line + 1 - dd->gp.yLineBias;
2329
				x = XMAP(at);
-
 
2330
				a = 0.0;
2308
				a = 0.0;
2331
				xadj = GP->adj;
2309
				xadj = mathDevice->gp.adj;
2332
				yadj = 0.0;
2310
				yadj = 0.0;
2333
			}
2311
			}
-
 
2312
			coords = MAR1;
2334
			break;
2313
			break;
2335
		case 2:
2314
		case 2:
2336
			if (las == 1 || las == 2) {
2315
			if (las == 1 || las == 2) {
2337
				x = GP->plt[0] - xInchtoFig(xChartoInch(GP->cexbase * GP->mex * (line + GP->yLineBias)));
2316
				at = at + GConvertYUnits(dd->gp.yLineBias,
-
 
2317
							 LINES, USER, dd);
2338
				y = YMAP(at) + yInchtoFig(yChartoInch(GP->cexbase * GP->mex * GP->yLineBias));
2318
				line = line + dd->gp.yLineBias;
2339
				a = 0.0;
2319
				a = 0.0;
2340
				xadj = 1.0;
2320
				xadj = 1.0;
2341
				yadj = 0.5;
2321
				yadj = 0.5;
2342
			}
2322
			}
2343
			else {
2323
			else {
2344
				x = GP->plt[0] - xInchtoFig(xChartoInch(GP->cexbase * GP->mex * (line + GP->yLineBias)));
-
 
2345
				y = YMAP(at);
2324
				line = line + dd->gp.yLineBias;
2346
				a = 90.0;
2325
				a = 90.0;
2347
				xadj = GP->adj;
2326
				xadj = mathDevice->gp.adj;
2348
				yadj = 0.0;
2327
				yadj = 0.0;
2349
			}
2328
			}
-
 
2329
			coords = MAR2;
2350
			break;
2330
			break;
2351
		case 3:
2331
		case 3:
2352
			if (las == 2) {
2332
			if (las == 2) {
2353
				y = GP->plt[3] + yInchtoFig(yChartoInch(GP->cexbase * GP->mex * (line + GP->yLineBias)));
2333
				at = at - GConvertXUnits(dd->gp.yLineBias,
-
 
2334
							 LINES, USER, dd);
2354
				x = XMAP(at) - xInchtoFig(xChartoInch(GP->cexbase * GP->mex * GP->yLineBias));
2335
				line = line + dd->gp.yLineBias;
2355
				a = 90.0;
2336
				a = 90.0;
2356
				xadj = 0.0;
2337
				xadj = 0.0;
2357
				yadj = 0.5;
2338
				yadj = 0.5;
2358
			}
2339
			}
2359
			else {
2340
			else {
2360
				y = GP->plt[3] + yInchtoFig(yChartoInch(GP->cexbase * GP->mex * (line + GP->yLineBias)));
-
 
2361
				x = XMAP(at);
2341
				line = line + dd->gp.yLineBias;
2362
				a = 0.0;
2342
				a = 0.0;
2363
				xadj = GP->adj;
2343
				xadj = mathDevice->gp.adj;
2364
				yadj = 0.0;
2344
				yadj = 0.0;
2365
			}
2345
			}
-
 
2346
			coords = MAR3;
2366
			break;
2347
			break;
2367
		case 4:
2348
		case 4:
2368
			if (las == 1 || las == 2) {
2349
			if (las == 1 || las == 2) {
2369
				x = GP->plt[1] + xInchtoFig(xChartoInch(GP->cexbase * GP->mex * (line + GP->yLineBias)));
2350
				at = at + GConvertYUnits(dd->gp.yLineBias,
-
 
2351
							 LINES, USER, dd);
2370
				y = YMAP(at) + yInchtoFig(yChartoInch(GP->cexbase * GP->mex * GP->yLineBias));
2352
				line = line + dd->gp.yLineBias;
2371
				a = 0.0;
2353
				a = 0.0;
2372
				xadj = 0.0;
2354
				xadj = 0.0;
2373
				yadj = 0.5;
2355
				yadj = 0.5;
2374
			}
2356
			}
2375
			else {
2357
			else {
2376
				x = GP->plt[1] + xInchtoFig(xChartoInch(GP->cexbase * GP->mex * (line + 1 - GP->yLineBias)));
2358
				line = line + 1 - dd->gp.yLineBias;
2377
				y = YMAP(at);
-
 
2378
				a = 90.0;
2359
				a = 90.0;
2379
				xadj = GP->adj;
2360
				xadj = mathDevice->gp.adj;
2380
				yadj = 0.0;
2361
				yadj = 0.0;
2381
			}
2362
			}
-
 
2363
			coords = MAR4;
2382
			break;
2364
			break;
2383
		}
2365
		}
2384
		GMathText(x, y, str, xadj, yadj, a);
2366
		GMathText(at, line, coords, str, xadj, yadj, a, dd);
2385
	}
2367
	}
2386
}
2368
}
2387
 
2369
 
2388
#else
2370
#else
2389
 
2371