home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / lib / layout / layhrule.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  6.3 KB  |  281 lines

  1. /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  2.  *
  3.  * The contents of this file are subject to the Netscape Public License
  4.  * Version 1.0 (the "NPL"); you may not use this file except in
  5.  * compliance with the NPL.  You may obtain a copy of the NPL at
  6.  * http://www.mozilla.org/NPL/
  7.  *
  8.  * Software distributed under the NPL is distributed on an "AS IS" basis,
  9.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
  10.  * for the specific language governing rights and limitations under the
  11.  * NPL.
  12.  *
  13.  * The Initial Developer of this code under the NPL is Netscape
  14.  * Communications Corporation.  Portions created by Netscape are
  15.  * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
  16.  * Reserved.
  17.  */
  18.  
  19. #include "xp.h"
  20. #include "pa_parse.h"
  21. #include "layout.h"
  22. #include "laystyle.h"
  23.  
  24. #ifdef PROFILE
  25. #pragma profile on
  26. #endif
  27.  
  28. #ifdef XP_MAC
  29. # ifdef XP_TRACE
  30. #  undef XP_TRACE
  31. # endif
  32. # define XP_TRACE(X)
  33. #else
  34. #ifndef XP_TRACE
  35. # define XP_TRACE(X) fprintf X
  36. #endif
  37. #endif /* XP_MAC */
  38.  
  39.  
  40. #define    DEFAULT_HR_THICKNESS    2
  41.  
  42.  
  43. /* This function is now only called during relayout */
  44. void
  45. lo_FillInHorizontalRuleGeometry(MWContext *context, lo_DocState *state, LO_HorizRuleStruct *hrule)
  46. {
  47.     int32 doc_width;
  48.  
  49.     hrule->ele_id = NEXT_ELEMENT;
  50.     hrule->x = state->x;
  51.     hrule->x_offset = 0;
  52.     hrule->y = state->y;
  53.     hrule->y_offset = 0;
  54.  
  55.     state->line_height = FEUNITS_Y(hrule->thickness, context) +
  56.         FEUNITS_Y(2, context);
  57.     /*
  58.      * horizontal rules are always at least as tall
  59.      * as the default line height.
  60.      */
  61.     if (state->line_height < state->default_line_height)
  62.     {
  63.         state->line_height = state->default_line_height;
  64.     }
  65.     hrule->height = FEUNITS_Y(hrule->thickness, context);        
  66.  
  67.     /* Set hrule->width  */
  68.     doc_width = state->right_margin - state->left_margin;
  69.     if (hrule->width_in_initial_layout > 0) 
  70.     {
  71.         /* Absolute width was specified in initial layout*/
  72.         hrule->width = hrule->width_in_initial_layout;
  73.     }
  74.     else if (hrule->percent_width > 0 ) 
  75.     {
  76.         /* Percent width was specified in initial layout */
  77.         int32 val = hrule->percent_width;
  78.         if (state->allow_percent_width == FALSE) 
  79.         {
  80.             val = 1;
  81.         }
  82.         else 
  83.         {
  84.             val = doc_width * val / 100;
  85.         }
  86.         hrule->width = val;
  87.     }
  88.     else 
  89.     {
  90.         /* No width was specified in initial layout */
  91.         if (state->allow_percent_width == FALSE) 
  92.         {
  93.             hrule->width = 1;
  94.         }
  95.         else
  96.         {
  97.             hrule->width = doc_width;
  98.         }
  99.     }
  100.  
  101.     hrule->y_offset = (state->line_height - hrule->thickness) / 2;
  102. }
  103.  
  104. void
  105. lo_UpdateStateAfterHorizontalRule(lo_DocState *state, LO_HorizRuleStruct *hrule)
  106. {
  107.     state->x = state->x + hrule->x_offset + hrule->width;
  108.     state->linefeed_state = 0;
  109.     state->at_begin_line = FALSE;
  110.     state->cur_ele_type = LO_HRULE;
  111. }
  112.  
  113. void
  114. lo_StartHorizontalRuleLayout(MWContext *context,
  115.                              lo_DocState *state,
  116.                              LO_HorizRuleStruct *hrule)
  117. {
  118.   lo_PushAlignment(state, P_HRULE, hrule->alignment);
  119.  
  120.   lo_FillInHorizontalRuleGeometry(context, state, hrule);
  121. }
  122.  
  123. void
  124. lo_FinishHorizontalRuleLayout(MWContext *context,
  125.                               lo_DocState *state,
  126.                               LO_HorizRuleStruct *hrule)
  127. {
  128.   lo_AlignStack *aptr;
  129.  
  130.   aptr = lo_PopAlignment(state);
  131.   if (aptr != NULL)
  132.     {
  133.       XP_DELETE(aptr);
  134.     }
  135. }
  136.  
  137. void
  138. lo_HorizontalRule(MWContext *context, lo_DocState *state, PA_Tag *tag)
  139. {
  140.     LO_HorizRuleStruct *hrule;
  141.     PA_Block buff;
  142.     char *str;
  143.     int32 val;
  144.  
  145.     hrule = (LO_HorizRuleStruct *)lo_NewElement(context, state, LO_HRULE, NULL, 0);
  146.     if (hrule == NULL)
  147.     {
  148.         return;
  149.     }
  150.  
  151.     hrule->type = LO_HRULE;    
  152.     hrule->width = state->right_margin - state->left_margin;
  153.     hrule->height = 0;
  154.     hrule->next = NULL;
  155.     hrule->prev = NULL;
  156.  
  157.     hrule->end_x = 0;
  158.     hrule->end_y = 0;
  159.  
  160.     hrule->FE_Data = NULL;
  161.     hrule->alignment = LO_ALIGN_CENTER;
  162.     hrule->thickness = DEFAULT_HR_THICKNESS;
  163.  
  164.     hrule->ele_attrmask = LO_ELE_SHADED;
  165.  
  166.     hrule->sel_start = -1;
  167.     hrule->sel_end = -1;
  168.     hrule->percent_width = 0;
  169.     hrule->width_in_initial_layout = 0;
  170.  
  171.     buff = lo_FetchParamValue(context, tag, PARAM_ALIGN);
  172.     if (buff != NULL)
  173.       {
  174.         PA_LOCK(str, char *, buff);
  175.         if (pa_TagEqual("left", str))
  176.           {
  177.             hrule->alignment = LO_ALIGN_LEFT;
  178.           }
  179.         else if (pa_TagEqual("right", str))
  180.           {
  181.             hrule->alignment = LO_ALIGN_RIGHT;
  182.           }
  183.         PA_UNLOCK(buff);
  184.         PA_FREE(buff);
  185.       }
  186.     else if (state->align_stack)
  187.       {
  188.         hrule->alignment = state->align_stack->alignment;
  189.       }
  190.     
  191.     buff = lo_FetchParamValue(context, tag, PARAM_SIZE);
  192.     if (buff != NULL)
  193.       {
  194.         PA_LOCK(str, char *, buff);
  195.         val = XP_ATOI(str);
  196.         if (val < 1)
  197.         {
  198.             val = 1;
  199.         }
  200.         else if (val > 100)
  201.         {
  202.             val = 100;
  203.         }
  204.         hrule->thickness = (intn) val;
  205.         PA_UNLOCK(buff);
  206.         PA_FREE(buff);
  207.     }
  208.  
  209.     buff = lo_FetchParamValue(context, tag, PARAM_WIDTH);
  210.     if (buff != NULL)
  211.     {
  212.         Bool is_percent;
  213.  
  214.         PA_LOCK(str, char *, buff);
  215.         val = lo_ValueOrPercent(str, &is_percent);
  216.         if (is_percent != FALSE)
  217.         {
  218.             hrule->percent_width = val;
  219.         }
  220.         else
  221.         {
  222.             hrule->percent_width = 0;
  223.             hrule->width_in_initial_layout = val;   /* Store absolute width for use in relayout*/
  224.             val = FEUNITS_X(val, context);
  225.         }
  226.         hrule->width = val;
  227.         PA_UNLOCK(buff);
  228.         PA_FREE(buff);
  229.     }
  230.  
  231.     /* Possible bug here if LO_GetWidthFromStyleSheet() is converting % widths to
  232.        absolute widths */
  233.     val = LO_GetWidthFromStyleSheet(context, state);
  234.     if(val)
  235.       {
  236.         hrule->percent_width = 0;
  237.         hrule->width = val;
  238.         hrule->width_in_initial_layout = val;        /* Store absolute width for use in relayout */
  239.       }    
  240.  
  241.     buff = lo_FetchParamValue(context, tag, PARAM_NOSHADE);
  242.     if (buff != NULL)
  243.     {
  244.         hrule->ele_attrmask &= (~(LO_ELE_SHADED));
  245.         PA_FREE(buff);
  246.     }
  247.  
  248.     /*
  249.      * Alignment of HRULE now done before we ever get here.
  250.     if (state->allow_percent_width != FALSE)
  251.     {
  252.         if (hrule->alignment == LO_ALIGN_CENTER)
  253.         {
  254.             hrule->x_offset = (doc_width - hrule->width) / 2;
  255.         }
  256.         else if (hrule->alignment == LO_ALIGN_RIGHT)
  257.         {
  258.             hrule->x_offset = doc_width - hrule->width;
  259.         }
  260.     }
  261.     if (hrule->x_offset < 0)
  262.     {
  263.         hrule->x_offset = state->left_margin;
  264.     }
  265.      */
  266.  
  267.     lo_StartHorizontalRuleLayout(context, state, hrule);
  268.  
  269.     lo_AppendToLineList(context, state, (LO_Element *)hrule, 0);
  270.  
  271.     lo_UpdateStateAfterHorizontalRule(state, hrule);
  272.  
  273.     lo_SoftLineBreak(context, state, FALSE);
  274.  
  275.     lo_FinishHorizontalRuleLayout(context, state, hrule);
  276. }
  277.  
  278. #ifdef PROFILE
  279. #pragma profile off
  280. #endif
  281.