Relations among lines and characters

From Apache OpenOffice Wiki
Jump to: navigation, search

History

  • Last update: March 4, 2008 by tora

Goals

This sub-project aims at providing users with more sophisticated ways to specify the number of lines per page and the number of characters per line.

Four numbers in the tab page 'Text Grid'
Grid lines and spacing 0021.png

There are four numbers in the pane Grid layout:

  • Lines per page
  • Characters per line
  • Max. base text size
  • Max. Ruby text size

Background

User wants to specify the number of lines per page and the number of characters and does not usually take care of size of ruby text and base text. This is one of the user scenarios. A teacher in a school gives an assignment to his/her students to submit a report written on a sheet with 20 lines times 20 characters. So the student tries to give the numbers to OpenOffice.org Writer.

With current implementation of Writer, the attempt will unfortunately result in failure. Why? The constraint among the four numbers is somewhat strange from Asian user's point of view.

Asian user wants to have a sheet with proper number of lines and characters. The grids constructed with the number of lines and characters are appropriately spread all over the drawable area of sheet.

Approach

We will consider not only four numbers, but also height and width of drawable area.

Entry How it should work
Lines per page
  • Increasing the value of Lines and page decrease Max. Ruby text size first.
  • When Max. Ruby text size reaches at 0.05pt, then Max. base text size starts to be decreased.
  • When sum of Max. base text size and Max. Ruby text size reaches at the certain value calculated with Characters per line, an attempt of increasing the value of lines per page is rejected.
Characters per line Increasing the value of Character per page ...
Max. base text size (It is difficult to explain this specification in a written text)
Max. Ruby text size (see the sample implementation cited below.)

Sample implementation

#define DIVIDE(x,y) ((int)( ( ( 1000L * (x) / (y) ) + 500 ) / 1000 ))

// i53425
sal_Bool SwTextGridPage::TextSizeChangeHandle()
{
    sal_Int32 nTextSize = aTextSizeMF.Denormalize(aTextSizeMF.GetValue(FUNIT_TWIP));
    UpdateFixedSpace();
    sal_Int32 nLinesPerPage = aLinesPerPageNF.GetValue();
    sal_Int32 nPageHeight = m_aPageSize.Height();
    sal_Int32 nLineHeight = DIVIDE( nPageHeight, nLinesPerPage );
    sal_Int32 nRubySize = nLineHeight - nTextSize;
    sal_Bool bRet = true;

    if(nRubySize<1)
    {
	nRubySize = 1;
	nLineHeight = nTextSize + nRubySize;
	nLinesPerPage = DIVIDE( nPageHeight, nLineHeight );
	if (nLinesPerPage<1)
	{
	    nLinesPerPage = 1;
	    nLineHeight = DIVIDE( nPageHeight, nLinesPerPage );
	    nTextSize = nLineHeight - nRubySize;
	    aTextSizeMF.SetValue(aTextSizeMF.Normalize(nTextSize), FUNIT_TWIP);	
	    UpdateFixedSpace();
	    bRet = false;
	}
	aLinesPerPageNF.SetValue(nLinesPerPage);
    }
    aRubySizeMF.SetValue(aRubySizeMF.Normalize(nRubySize), FUNIT_TWIP);
    return bRet;
}

// i53425
sal_Bool SwTextGridPage::TextSizeChangeHandle_()
{
    sal_Int32 nTextSize = aTextSizeMF.Denormalize(aTextSizeMF.GetValue(FUNIT_TWIP));
    UpdateFixedSpace();
    sal_Int32 nPageWidth = m_aPageSize.Width();
    sal_Int32 nCharsPerLine = DIVIDE( nPageWidth, nTextSize );
    sal_Bool bRet = true;

    if (nCharsPerLine<1)
    {
	nCharsPerLine = 1;
	nTextSize = DIVIDE( nPageWidth, nCharsPerLine );
	aTextSizeMF.SetValue(aTextSizeMF.Normalize(nTextSize), FUNIT_TWIP);	
	UpdateFixedSpace();
	bRet = false;
    }
    aCharsPerLineNF.SetValue(nCharsPerLine);
    m_bRubyUserValue = sal_False;
    return bRet;
}

// i53425
sal_Bool SwTextGridPage::RubySizeChangeHandle()
{
    sal_Int32 nRubySize = aRubySizeMF.Denormalize(aRubySizeMF.GetValue(FUNIT_TWIP));
    sal_Int32 nLinesPerPage = aLinesPerPageNF.GetValue();
    sal_Int32 nPageHeight = m_aPageSize.Height();
    sal_Int32 nLineHeight = DIVIDE( nPageHeight, nLinesPerPage );
    sal_Int32 nTextSize = nLineHeight - nRubySize;
    sal_Bool bRet = true;

    if(nTextSize<1)
    {
	nTextSize = 1;
	nLineHeight = nTextSize + nRubySize;
	nLinesPerPage = DIVIDE( nPageHeight, nLineHeight );
	if (nLinesPerPage<1)
	{
	    nLinesPerPage = 1;
	    nLineHeight = DIVIDE( nPageHeight, nLinesPerPage );
	    nRubySize = nLineHeight - nTextSize;
	    aRubySizeMF.SetValue(aRubySizeMF.Normalize(nRubySize), FUNIT_TWIP);
	    bRet = false;
	}
	aLinesPerPageNF.SetValue(nLinesPerPage);
    }
    aTextSizeMF.SetValue(aTextSizeMF.Normalize(nTextSize), FUNIT_TWIP);	
    UpdateFixedSpace();
    return bRet;
}

// i53425
sal_Bool SwTextGridPage::RubySizeChangeHandle_()
{
    sal_Int32 nRubySize = aRubySizeMF.Denormalize(aRubySizeMF.GetValue(FUNIT_TWIP));
    sal_Int32 nTextSize = aTextSizeMF.Denormalize(aTextSizeMF.GetValue(FUNIT_TWIP));
    sal_Int32 nLineHeight = nTextSize + nRubySize;
    sal_Int32 nPageHeight = m_aPageSize.Height();
    sal_Int32 nLinesPerPage = DIVIDE( nPageHeight, nLineHeight );
    sal_Bool bRet = true;

    if(nLinesPerPage<1)
    {
	nLinesPerPage = 1;
	nLineHeight = DIVIDE( nPageHeight, nLinesPerPage );
	nTextSize = nLineHeight - nRubySize;
	if (nTextSize<1)
	{
	    nTextSize = 1;
	    nLineHeight = DIVIDE( nPageHeight, nLinesPerPage );
	    nRubySize = nLineHeight - nTextSize;
	    aRubySizeMF.SetValue(aRubySizeMF.Normalize(nRubySize), FUNIT_TWIP);
	    bRet = false;
	}
	aTextSizeMF.SetValue(aTextSizeMF.Normalize(nTextSize), FUNIT_TWIP);	
	UpdateFixedSpace();
    }
    aLinesPerPageNF.SetValue(nLinesPerPage);
    return bRet;
}

// i53425
sal_Bool SwTextGridPage::CharsPerLineChangeHandle()
{
    sal_Int32 nCharsPerLine = aCharsPerLineNF.GetValue();
    sal_Int32 nPageWidth = m_aPageSize.Width();
    sal_Int32 nTextSize = DIVIDE( nPageWidth, nCharsPerLine );
    sal_Bool bRet = true;

    if (nTextSize<1)
    {
	nTextSize = 1;
	nCharsPerLine = DIVIDE( nPageWidth, nTextSize );
	aCharsPerLineNF.SetValue(nCharsPerLine);

	bRet = false;
    }
    aTextSizeMF.SetValue(aTextSizeMF.Normalize(nTextSize), FUNIT_TWIP);	
    UpdateFixedSpace();
    m_nRubyUserValue = nTextSize;
    m_bRubyUserValue = sal_True;
    return bRet;
}

// i53425
sal_Bool SwTextGridPage::LinesPerPageChangeHandle()
{
    sal_Int32 nLinesPerPage = aLinesPerPageNF.GetValue();
    sal_Int32 nTextSize = aTextSizeMF.Denormalize(aTextSizeMF.GetValue(FUNIT_TWIP));
    sal_Int32 nPageHeight = m_aPageSize.Height();
    sal_Int32 nLineHeight = DIVIDE( nPageHeight, nLinesPerPage );
    sal_Int32 nRubySize = nLineHeight - nTextSize;
    sal_Bool bRet = true;

    if(nRubySize<1)
    {
	nRubySize = 1;
	nTextSize = nLineHeight - nRubySize;
	if (nTextSize<1)
	{
	    nTextSize = 1;
	    nLineHeight = nTextSize + nRubySize;
	    nLinesPerPage = DIVIDE( nPageHeight, nLineHeight );
	    aLinesPerPageNF.SetValue(nLinesPerPage);
	    bRet = false;
	}
	aTextSizeMF.SetValue(aTextSizeMF.Normalize(nTextSize), FUNIT_TWIP);	
	UpdateFixedSpace();
    }
    aRubySizeMF.SetValue(aRubySizeMF.Normalize(nRubySize), FUNIT_TWIP);
    return bRet;
}

// i53425
// IMPL_LINK(SwTextGridPage, GridModifyHdl, void*, EMPTYARG)
// {
//     //set maximum for Lines per page
//     sal_Int32 nMaxLines = m_aPageSize.Height() /
//                 (   aTextSizeMF.Denormalize(aTextSizeMF.GetValue(FUNIT_TWIP)) +
//                     aRubySizeMF.Denormalize(aRubySizeMF.GetValue(FUNIT_TWIP)));
//     aLinesPerPageNF.SetMax(nMaxLines);
IMPL_LINK(SwTextGridPage, GridModifyHdl, SpinField*, pField)
{
    if(&aTextSizeMF == pField)
    {
	TextSizeChangeHandle();
	TextSizeChangeHandle_();
    }
    else if(&aRubySizeMF == pField)
    {
	RubySizeChangeHandle();
	TextSizeChangeHandle_();
    }
    else if(&aCharsPerLineNF == pField)
    {
	CharsPerLineChangeHandle();
	TextSizeChangeHandle();
    }
    else if(&aLinesPerPageNF == pField)
    {
	LinesPerPageChangeHandle();
	TextSizeChangeHandle_();
    }
    const SfxItemSet& rOldSet = GetItemSet();
    SfxItemSet aSet(rOldSet);
    const SfxItemSet* pExSet = GetTabDialog()->GetExampleSet();
    if(pExSet)
        aSet.Put(*pExSet);
    PutGridItem(aSet);
    aExampleWN.UpdateExample(aSet);
    return 0;
}

Issues

Details can be found in the following issues:

Note that the patch attached in the issue above is obsolete.

Modules

The following modules have been modified.

Module Modifications
sw
  • some methods of class SwTextGridPage in sw/source/ui/misc/pggrid.cxx and sw/source/ui/inc/pggrid.hxx
Personal tools