00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "StringBox.h"
00010 #include "Xcall1.h"
00011 #include "GetProperty.h"
00012 #include "Axes.h"
00013 #include "math_graphics.h"
00014 #include "PloEch.h"
00015 #include "MALLOC.h"
00016 #include "CurrentObjectsManagement.h"
00017 #include "ObjectSelection.h"
00018
00019
00020 void getStringBbox( char * string, int center[2], int rect[4] )
00021 {
00022 C2F(dr)("xstringl",string,&(center[0]),&(center[1]),rect,PI0,PI0,PI0,PD0,PD0,PD0,PD0,9L,bsiz);
00023 }
00024
00025 void callXstringL( char * string, int posX, int posY, int boundingRect[4] )
00026 {
00027 sciPointObj * parentSubWin = sciGetFirstTypedSelectedSon( sciGetCurrentFigure(), SCI_SUBWIN ) ;
00028
00029 updateScaleIfRequired( parentSubWin ) ;
00030
00031
00032 C2F(dr)("xstringl",string,&posX,&posY,boundingRect,PI0,PI0,PI0,PD0,PD0,PD0,PD0,0L,0L);
00033
00034 }
00035
00036 void getStringBox( char ** text ,
00037 double textPos[2] ,
00038 int textDim[2] ,
00039 BOOL autoSize ,
00040 double userSize[2] ,
00041 double angle ,
00042 int fontId ,
00043 int fontSize ,
00044 double corners[4][2] )
00045 {
00046 int pos[2] ;
00047 int textSize[2] = {0,0} ;
00048 int corn[4][2] ;
00049 StringMatrix * strings = newCompleteMatrix( (void **) text, textDim[0], textDim[1] ) ;
00050
00051
00052 pos[0] = XDouble2Pixel( textPos[0] ) ;
00053 pos[1] = YDouble2Pixel( textPos[1] ) ;
00054
00055 if ( !autoSize )
00056 {
00057 textSize[0] = WDouble2Pixel( textPos[0], userSize[0] ) ;
00058 textSize[1] = HDouble2Pixel( textPos[1], userSize[1] ) ;
00059 }
00060
00061
00062 getStringsPositions( strings, &fontId, &fontSize, pos, autoSize, textSize, FALSE, angle, NULL, corn ) ;
00063
00064
00065
00066 corners[0][0] = XDPixel2Double( corn[0][0] ) ;
00067 corners[0][1] = YDPixel2Double( corn[0][1] ) ;
00068
00069 corners[1][0] = XDPixel2Double( corn[1][0] ) ;
00070 corners[1][1] = YDPixel2Double( corn[1][1] ) ;
00071
00072 corners[2][0] = XDPixel2Double( corn[2][0] ) ;
00073 corners[2][1] = YDPixel2Double( corn[2][1] ) ;
00074
00075 corners[3][0] = XDPixel2Double( corn[3][0] ) ;
00076 corners[3][1] = YDPixel2Double( corn[3][1] ) ;
00077
00078
00079 desallocateMatrix( strings ) ;
00080
00081 }
00082
00083 void getStringsRect( StringMatrix * strMat ,
00084 int textPos[2] ,
00085 Vect2iMatrix * stringPosition ,
00086 int boundingBox[4][2] )
00087 {
00088
00089 int hSpace = getStringHorizontalSpace() ;
00090 int vSpace = getStringVerticalSpace() ;
00091 int * rowHeight ;
00092 int * colWidth ;
00093
00094 int i ;
00095 int j ;
00096 int nbRow = getMatNbRow( strMat ) ;
00097 int nbCol = getMatNbCol( strMat ) ;
00098 int rect[4] ;
00099 int curHeight = 0 ;
00100 int curWidth = 0 ;
00101
00102
00103
00104 rowHeight = MALLOC( (nbRow + 1) * sizeof( int ) ) ;
00105 colWidth = MALLOC( (nbCol + 1) * sizeof( int ) ) ;
00106
00107
00108
00109
00110
00111
00112 rowHeight[nbRow] = textPos[1] ;
00113
00114
00115 for ( i = nbRow - 1 ; i >= 0 ; i-- )
00116 {
00117 for ( j = 0 ; j < nbCol ; j++ )
00118 {
00119 getStringBbox( getStrMatElement( strMat, i, j ), textPos, rect ) ;
00120 curHeight = Max( curHeight, rect[3] ) ;
00121 }
00122
00123 rowHeight[i] = rowHeight[i+1] - curHeight - vSpace ;
00124 curHeight = 0 ;
00125 }
00126
00127
00128 colWidth[0] = textPos[0] ;
00129
00130 for ( j = 0 ; j < nbCol ; j++ )
00131 {
00132 for ( i = nbRow - 1 ; i >= 0 ; i-- )
00133 {
00134 getStringBbox( getStrMatElement( strMat, i, j ), textPos, rect ) ;
00135 curWidth = Max( curWidth, rect[2] ) ;
00136 }
00137 colWidth[j+1] = colWidth[j] + curWidth + hSpace ;
00138 curWidth = 0 ;
00139 }
00140
00141
00142 if ( stringPosition != NULL )
00143 {
00144 for ( i = 0 ; i <= nbRow ; i++ )
00145 {
00146 for ( j = 0 ; j <= nbCol ; j++ )
00147 {
00148 int intersect[2] = { colWidth[j], rowHeight[i] } ;
00149 copyVect2iMatElement( stringPosition, i, j, intersect ) ;
00150 }
00151 }
00152 }
00153
00154
00155 boundingBox[0][0] = textPos[0] ;
00156 boundingBox[0][1] = textPos[1] ;
00157
00158 boundingBox[1][0] = boundingBox[0][0] ;
00159 boundingBox[1][1] = rowHeight[0] ;
00160
00161 boundingBox[2][0] = colWidth[nbCol] ;
00162 boundingBox[2][1] = boundingBox[1][1] ;
00163
00164 boundingBox[3][0] = boundingBox[2][0] ;
00165 boundingBox[3][1] = boundingBox[0][1] ;
00166
00167 FREE( rowHeight ) ;
00168 FREE( colWidth ) ;
00169
00170 }
00171
00172 void getStringsRectSized( StringMatrix * strMat ,
00173 int textPos[2] ,
00174 Vect2iMatrix * stringPosition ,
00175 int boundingBox[4][2],
00176 int userSize[2] ,
00177 int * newFontSize )
00178 {
00179 integer curFont[2] ;
00180 integer verbose = 0 ;
00181 integer v ;
00182 integer fontSizeOne = 1 ;
00183 double homothFactors[2] ;
00184
00185
00186
00187
00188
00189 C2F(dr)("xget","font",&verbose,curFont,&v,PI0,PI0,PI0,PD0,PD0,PD0,PD0,5L,5L);
00190
00191
00192 C2F(dr)("xset","font",&(curFont[0]),&fontSizeOne,PI0,PI0,PI0,PI0,PD0,PD0,PD0,PD0,0L,0L);
00193
00194
00195 getStringsRect( strMat, textPos, stringPosition, boundingBox ) ;
00196
00197
00198
00199 homothFactors[0] = ((double) userSize[0]) / ( boundingBox[2][0] - boundingBox[0][0] ) ;
00200 homothFactors[1] = ((double) userSize[1]) / ( boundingBox[0][1] - boundingBox[2][1] ) ;
00201
00202
00203 iHomothety2D( boundingBox[1], boundingBox[0], homothFactors, boundingBox[1] ) ;
00204 iHomothety2D( boundingBox[2], boundingBox[0], homothFactors, boundingBox[2] ) ;
00205 iHomothety2D( boundingBox[3], boundingBox[0], homothFactors, boundingBox[3] ) ;
00206
00207
00208 if ( stringPosition != NULL )
00209 {
00210 homothVect2iMatrix( stringPosition, boundingBox[0], homothFactors ) ;
00211 *newFontSize = computeSuitableFont( strMat, stringPosition ) ;
00212 }
00213
00214
00215 C2F(dr)("xset","font",&curFont[0],&curFont[1],PI0,PI0,PI0,PI0,PD0,PD0,PD0,PD0,0L,0L);
00216 }
00217
00218 void getStringsPositions( StringMatrix * strMat ,
00219 int * fontId ,
00220 int * fontSize ,
00221 int textPos[2] ,
00222 BOOL autoSize ,
00223 int textSize[2] ,
00224 BOOL centerPos ,
00225 double angle ,
00226 Vect2iMatrix * stringPosition,
00227 int boundingBox[4][2] )
00228 {
00229 integer curFont[2] ;
00230 integer verbose = 0 ;
00231 integer v ;
00232 int trans[2] ;
00233
00234 if ( autoSize )
00235 {
00236
00237
00238 C2F(dr)("xget","font",&verbose,curFont,&v,PI0,PI0,PI0,PD0,PD0,PD0,PD0,5L,5L);
00239
00240
00241 C2F(dr)("xset","font",fontId,fontSize,PI0,PI0,PI0,PI0,PD0,PD0,PD0,PD0,0L,0L);
00242
00243
00244 getStringsRect( strMat, textPos, stringPosition, boundingBox ) ;
00245
00246
00247 C2F(dr)("xset","font",&curFont[0],&curFont[1],PI0,PI0,PI0,PI0,PD0,PD0,PD0,PD0,0L,0L);
00248 }
00249 else
00250 {
00251 getStringsRectSized( strMat, textPos, stringPosition, boundingBox, textSize, fontSize ) ;
00252 }
00253
00254
00255
00256
00257
00258 getStringPositionTranslation( centerPos, textSize, boundingBox, trans ) ;
00259 if ( stringPosition != NULL )
00260 {
00261 translateVect2iMatrix( stringPosition, trans ) ;
00262 }
00263 translateBoundingBox( boundingBox, trans ) ;
00264
00265
00266 if ( Abs( angle ) > EPSILON )
00267 {
00268 if ( stringPosition != NULL )
00269 {
00270 rotateVect2iMatrix( stringPosition, textPos, angle ) ;
00271 }
00272 rotateBoundingBox( boundingBox, textPos, angle ) ;
00273 }
00274
00275 }
00276
00277 void getTextBoundingBox( sciPointObj * pText ,
00278 int cornPix[4][2],
00279 double corners[4][2] )
00280 {
00281 int fontId = sciGetFontStyle( pText ) ;
00282 int fontSize = sciGetFontDeciWidth( pText ) / 100 ;
00283 double angle = DEG2RAD( sciGetFontOrientation (pText) / 10 ) ;
00284 int position[2] ;
00285 double textPos[3] ;
00286 double userSize[2] ;
00287 int textSize[2] ;
00288 sciText * ppText = pTEXT_FEATURE( pText ) ;
00289 sciPointObj * parentSW = sciGetParentSubwin( pText ) ;
00290
00291
00292
00293 textPos[0] = ppText->x ;
00294 textPos[1] = ppText->y ;
00295 textPos[2] = ppText->z ;
00296
00297 updateScaleIfRequired( parentSW ) ;
00298
00299 if ( sciGetIs3d( pText ) )
00300 {
00301
00302 getPixelCoordinates( parentSW, textPos, position ) ;
00303 }
00304 else
00305 {
00306
00307 position[0] = XDouble2Pixel( textPos[0] ) ;
00308 position[1] = YDouble2Pixel( textPos[1] ) ;
00309 }
00310
00311 sciGetUserSize( pText, &(userSize[0]), &(userSize[1]) ) ;
00312
00313
00314 textSize[0] = PixelWidth2d( parentSW, ppText->x, userSize[0] ) ;
00315 textSize[1] = PixelHeight2d( parentSW, ppText->y, userSize[1] ) ;
00316
00317 if ( cornPix == NULL )
00318 {
00319 int corn[4][2] ;
00320
00321 getStringsPositions( sciGetText( pText ) ,
00322 &fontId ,
00323 &fontSize ,
00324 position ,
00325 sciGetAutoSize( pText ) ,
00326 textSize ,
00327 sciGetCenterPos( pText ),
00328 angle ,
00329 NULL ,
00330 corn ) ;
00331 if ( corners != NULL )
00332 {
00333
00334
00335 corners[0][0] = XDPixel2Double( corn[0][0] ) ;
00336 corners[0][1] = YDPixel2Double( corn[0][1] ) ;
00337
00338 corners[1][0] = XDPixel2Double( corn[1][0] ) ;
00339 corners[1][1] = YDPixel2Double( corn[1][1] ) ;
00340
00341 corners[2][0] = XDPixel2Double( corn[2][0] ) ;
00342 corners[2][1] = YDPixel2Double( corn[2][1] ) ;
00343
00344 corners[3][0] = XDPixel2Double( corn[3][0] ) ;
00345 corners[3][1] = YDPixel2Double( corn[3][1] ) ;
00346 }
00347 }
00348 else
00349 {
00350
00351 getStringsPositions( sciGetText( pText ) ,
00352 &fontId ,
00353 &fontSize ,
00354 position ,
00355 sciGetAutoSize( pText ) ,
00356 textSize ,
00357 sciGetCenterPos( pText ),
00358 angle ,
00359 NULL ,
00360 cornPix ) ;
00361
00362 if ( corners != NULL )
00363 {
00364
00365
00366 corners[0][0] = XDPixel2Double( cornPix[0][0] ) ;
00367 corners[0][1] = YDPixel2Double( cornPix[0][1] ) ;
00368
00369 corners[1][0] = XDPixel2Double( cornPix[1][0] ) ;
00370 corners[1][1] = YDPixel2Double( cornPix[1][1] ) ;
00371
00372 corners[2][0] = XDPixel2Double( cornPix[2][0] ) ;
00373 corners[2][1] = YDPixel2Double( cornPix[2][1] ) ;
00374
00375 corners[3][0] = XDPixel2Double( cornPix[3][0] ) ;
00376 corners[3][1] = YDPixel2Double( cornPix[3][1] ) ;
00377 }
00378 }
00379
00380 }
00381
00382 void getTextAabb( sciPointObj * pText ,
00383 int rectPix[4] ,
00384 int cornPix[4][2] )
00385 {
00386 if ( cornPix == NULL )
00387 {
00388
00389 getTextBoundingBox( pText, cornPix, NULL ) ;
00390
00391 if ( rectPix != NULL )
00392 {
00393 rectPix[0] = Min( cornPix[0][0], Min( cornPix[1][0], Min( cornPix[2][0], cornPix[3][0] ) ) ) ;
00394
00395 rectPix[1] = Max( cornPix[0][1], Max( cornPix[1][1], Max( cornPix[2][1], cornPix[3][1] ) ) ) ;
00396 rectPix[2] = Max( abs( cornPix[2][0] - cornPix[0][0] ), abs( cornPix[3][0] - cornPix[1][0] ) ) ;
00397 rectPix[3] = Max( abs( cornPix[2][1] - cornPix[0][1] ), abs( cornPix[3][1] - cornPix[1][1] ) ) ;
00398 }
00399 }
00400 else
00401 {
00402 getTextBoundingBox( pText, cornPix, NULL ) ;
00403
00404 if ( rectPix != NULL )
00405 {
00406 rectPix[0] = Min( cornPix[0][0], Min( cornPix[1][0], Min( cornPix[2][0], cornPix[3][0] ) ) ) ;
00407
00408 rectPix[1] = Max( cornPix[0][1], Max( cornPix[1][1], Max( cornPix[2][1], cornPix[3][1] ) ) ) ;
00409 rectPix[2] = Max( abs( cornPix[2][0] - cornPix[0][0] ), abs( cornPix[3][0] - cornPix[1][0] ) ) ;
00410 rectPix[3] = Max( abs( cornPix[2][1] - cornPix[0][1] ), abs( cornPix[3][1] - cornPix[1][1] ) ) ;
00411 }
00412 }
00413
00414 }
00415
00416
00417 void rotateBoundingBox( int boundingBox[4][2], int center[2], double angle )
00418 {
00419 if ( Abs( angle ) > EPSILON )
00420 {
00421 double cosAngle = cos( angle ) ;
00422 double sinAngle = sin( angle ) ;
00423 iRotate2Dim( boundingBox[0], center, cosAngle, sinAngle, boundingBox[0] ) ;
00424 iRotate2Dim( boundingBox[1], center, cosAngle, sinAngle, boundingBox[1] ) ;
00425 iRotate2Dim( boundingBox[2], center, cosAngle, sinAngle, boundingBox[2] ) ;
00426 iRotate2Dim( boundingBox[3], center, cosAngle, sinAngle, boundingBox[3] ) ;
00427 }
00428 }
00429
00430 void translateBoundingBox( int boundingBox[4][2], int trans[2] )
00431 {
00432 iTranslate2D( boundingBox[0], trans, boundingBox[0] ) ;
00433 iTranslate2D( boundingBox[1], trans, boundingBox[1] ) ;
00434 iTranslate2D( boundingBox[2], trans, boundingBox[2] ) ;
00435 iTranslate2D( boundingBox[3], trans, boundingBox[3] ) ;
00436
00437 }
00438
00439 int getStringVerticalSpace( void )
00440 {
00441 int rect[4] ;
00442 int pos[2] = {0,0} ;
00443 getStringBbox( " ", pos, rect ) ;
00444 return rect[3] ;
00445 }
00446
00447 int getStringHorizontalSpace( void )
00448 {
00449 int rect[4] ;
00450 int pos[2] = {0,0} ;
00451
00452 getStringBbox( " ", pos, rect ) ;
00453 return rect[2] ;
00454 }
00455
00456 BOOL isFittingInCell( char * string, int cellWidth, int cellHeight )
00457 {
00458 int rect[4] ;
00459 int pos[2] = {0,0} ;
00460
00461
00462 getStringBbox( string, pos, rect ) ;
00463
00464 if ( rect[2] < cellWidth && rect[3] < cellHeight )
00465 {
00466 return TRUE ;
00467 }
00468 return FALSE ;
00469 }
00470
00471 void getStringPositionTranslation( BOOL centeredPos, int textSize[2], int bbox[4][2], int trans[2] )
00472 {
00473 if ( centeredPos )
00474 {
00475 trans[0] = ( textSize[0] + bbox[0][0] - bbox[2][0] ) / 2 ;
00476 trans[1] = ( -textSize[1] + bbox[0][1] - bbox[2][1] ) / 2 ;
00477 }
00478 else
00479 {
00480 trans[0] = 0 ;
00481 trans[1] = 0 ;
00482 }
00483 }
00484
00485 int computeSuitableFont( StringMatrix * strMat, Vect2iMatrix * stringPosition )
00486 {
00487 int nbRow = getMatNbRow( strMat ) ;
00488 int nbCol = getMatNbCol( strMat ) ;
00489 int largestFont ;
00490 int smallestFont ;
00491 int i ;
00492 int j ;
00493 integer curFont[2] ;
00494 integer verbose = 0 ;
00495 integer v ;
00496
00497 C2F(dr)("xget","font",&verbose,curFont,&v,PI0,PI0,PI0,PD0,PD0,PD0,PD0,5L,5L) ;
00498
00499
00500
00501 C2F(dr)( "xfontmxs","", &smallestFont, &largestFont, PI0,PI0,PI0,PI0,PD0,PD0,PD0,PD0,0L,0L ) ;
00502
00503
00504 C2F(dr)("xset","font",&(curFont[0]),&largestFont,PI0,PI0,PI0,PI0,PD0,PD0,PD0,PD0,0L,0L);
00505
00506 for ( i = 0 ; i < nbRow ; i++ )
00507 {
00508 for ( j = 0 ; j < nbCol ; j++ )
00509 {
00510 int * blCorner = getVect2iMatElement( stringPosition, i , j ) ;
00511 int * urCorner = getVect2iMatElement( stringPosition, i + 1, j + 1 ) ;
00512 char * string = getStrMatElement( strMat, i, j ) ;
00513 int width = urCorner[0] - blCorner[0] ;
00514 int height = urCorner[1] - blCorner[1] ;
00515 while ( !isFittingInCell( string, width, height ) )
00516 {
00517 largestFont-- ;
00518 if ( largestFont == smallestFont )
00519 {
00520
00521 C2F(dr)("xset","font",&curFont[0],&curFont[1],PI0,PI0,PI0,PI0,PD0,PD0,PD0,PD0,0L,0L) ;
00522 return smallestFont ;
00523 }
00524
00525 C2F(dr)("xset","font",&(curFont[0]),&largestFont,PI0,PI0,PI0,PI0,PD0,PD0,PD0,PD0,0L,0L);
00526 }
00527 }
00528 }
00529
00530
00531 C2F(dr)("xset","font",&curFont[0],&curFont[1],PI0,PI0,PI0,PI0,PD0,PD0,PD0,PD0,0L,0L);
00532 return largestFont ;
00533
00534 }
00535