PageRenderTime 36ms CodeModel.GetById 13ms app.highlight 15ms RepoModel.GetById 1ms app.codeStats 0ms

/framework/experimental/graphic/GraphicHardBrokenLine.php

http://zoop.googlecode.com/
PHP | 302 lines | 128 code | 33 blank | 141 comment | 13 complexity | aa585fa85e7631798de9109fab639033 MD5 | raw file
  1<?php
  2class GraphicHardBrokenLine extends GraphicObject
  3{
  4	var $members;
  5	var $alignment;
  6	var $lineSpacing;
  7	var $doneDrawing;
  8	var $topIndent;
  9	var $bottomIndent;
 10	
 11	function GraphicHardBrokenLine()
 12	{
 13		$this->members = array();
 14		$this->alignment = 'left';
 15		$this->doneDrawing = 0;
 16	}
 17	
 18	function getUnwrappedWidth()
 19	{
 20		$total = 0;
 21		for($curMember = 0; $curMember < count($this->members); $curMember++)
 22		{
 23//			echo get_class($this->members[$curMember]);
 24			$total += $this->members[$curMember]->getUnwrappedWidth();
 25		}
 26		return $total;
 27	}
 28	
 29	function setBottomIndent($indent)
 30	{
 31		$this->bottomIndent = $indent;
 32	}
 33	
 34	function setLineSpacing($lineSpacing)
 35	{
 36		$this->lineSpacing = $lineSpacing;
 37	}
 38	
 39	function addMember($member)
 40	{
 41		$this->members[] = $member;
 42	}
 43	
 44	function setAlignment($alignment)
 45	{
 46		$this->alignment = $alignment;
 47	}
 48	
 49	function isBreakable()
 50	{
 51		return $this->members[0]->isBreakable();
 52	}
 53	
 54	function getMinHeight($width)
 55	{
 56		if($this->isBreakable())
 57		{
 58			return $this->members[0]->getMinHeight($width);
 59		}
 60		else
 61		{
 62			return $this->getHeight($width);
 63		}
 64	}
 65	
 66	function doneDrawing()
 67	{
 68		return $this->doneDrawing;
 69	}
 70	
 71	function forcePageBreak()
 72	{
 73		return $this->members[0]->forcePageBreak();
 74	}
 75	
 76	function draw($x, $y, $width, $reallyDraw = 1)
 77	{
 78		// echo "drawing hard broken line: $x, $y, $width, $reallyDraw<br>";
 79		
 80		// $width += 20;
 81		
 82		//	if there is nothing in it then just return 0
 83		if(count($this->members) == 0)
 84			return 0;
 85		
 86		/*
 87		//	if this is not an inline item then it should be all by itself and we
 88		//	need to just draw it and return		
 89		if( !$this->members[0]->isInline() )
 90		{
 91			assert( count($this->members[0]) == 1);
 92			
 93			switch($this->alignment)
 94			{
 95				case 'left':
 96					$curx = $x;
 97					break;
 98				case 'center':
 99					$curx = $x + (($width - $this->members[0]->getWidth()) / 2);
100					break;
101				case 'right':
102					$curx = $x + $width - $this->members[0]->getWidth();
103					break;
104				default:
105					trigger_error('invalid alignment specified: ' . $this->alignment);
106					break;
107			}
108			
109			$height = $this->members[0]->draw($curx, $y, $width, $reallyDraw);
110			
111			$this->doneDrawing = $this->members[0]->doneDrawing();
112			
113			return $height;
114		}
115		*/
116		assert($this->members[0]->isInline());
117		
118		//
119		//	this is a series of one or more inline items
120		//	we need to draw them all and wrap them to the width
121		//
122		
123		//
124		//	break everything up into soft broken lines
125		//
126		
127		$curMemberNumber = 0;
128		$lines = array();
129		$curLine = 0;
130		//$lines[$curLine] = &new GraphicSoftBrokenLine();
131		$curPos = 0;
132		$remainingWidth = $width;
133		
134		while($curMemberNumber < count($this->members))
135		{
136			//	get and verify the current member
137			$curMember = $this->members[$curMemberNumber];
138			assert(is_a($curMember, 'GraphicTextRun'));
139			
140			//	figure out how much if any of this member will fit onto the current line
141			$fitsLength = $curMember->getFitsLength($curPos, $remainingWidth);
142			// echo "$curPos, $remainingWidth $fitsLength<br>";
143			assert($curMember->getLength() >= $curPos + $fitsLength);
144			
145			//	if it all fits add it to the soft broken line, bump the member number and continue from the top
146			if($curPos + $fitsLength == $curMember->getLength())
147			{
148				if(!isset($lines[$curLine]))
149					$lines[$curLine] = &new GraphicSoftBrokenLine();
150				
151				$lines[$curLine]->addEntry($curMember, $curPos, $fitsLength);
152				$remainingWidth -= $curMember->getPartWidth($curPos, $fitsLength);
153				$curMemberNumber++;
154				$curPos = 0;
155			}
156			
157			//	if only part fits, add that part, bump the line number and continue from the top
158			else if($fitsLength > 0)
159			{
160				if(!isset($lines[$curLine]))
161					$lines[$curLine] = &new GraphicSoftBrokenLine();
162				
163				$lines[$curLine]->addEntry($curMember, $curPos, $fitsLength);
164				$curPos += $fitsLength;
165				
166				$curLine++;
167				$remainingWidth = $width;
168				// if($this->bottomIndent)
169				// 	$remainingWidth -= $this->bottomIndent;
170			}
171			
172			//	if none fits bump the line number and continue from the top
173			else
174			{
175				if($remainingWidth == $width)
176					trigger_error("single word will not fit in space");
177				
178				$curLine++;
179				$remainingWidth = $width;
180			}
181		}
182		
183		/*
184		while(true)
185		{
186			//	if everything is already handled then just break out of the loop
187			if($curMember >= count($this->members))
188				break;
189			
190			//	figure out how much of this member will fit onto the current line
191			$fitsLength = $this->members[$curMember]->getFitsLength($curPos, $remainingWidth);
192			
193			//	if the whole thing fits on the line
194			if($curPos + $fitsLength >= $this->members[$curMember]->getLength())
195			{
196				//	if this is the first item on the line then first create the line
197				if(!isset($lines[$curLine]))
198					$lines[$curLine] = &new GraphicSoftBrokenLine();
199				
200				$lines[$curLine]->addEntry($this->members[$curMember], $curPos, $fitsLength);
201				
202				$remainingWidth -= $this->members[$curMember]->getPartWidth($curPos, $fitsLength);
203				$curMember++;
204				$curPos = 0;
205			}
206			//	if it doesn't all fit but some fits
207			else if($fitsLength > 0)
208			{
209				//	if this is the first item on the line then first create the line
210				if(!isset($lines[$curLine]))
211					$lines[$curLine] = &new GraphicSoftBrokenLine();
212				
213				$lines[$curLine]->addEntry($this->members[$curMember], $curPos, $fitsLength);
214				$curPos += $fitsLength;
215				
216				$curLine++;
217				$remainingWidth = $width;
218				if($this->bottomIndent)
219					$remainingWidth -= $this->bottomIndent;
220			}
221			//	if none of it will fit???
222			else
223			{
224				echo "$curPos $fitsLength " . $this->members[$curMember]->getLength() . "<br>";
225				BUG("This should never happen.  Most likely you are trying to squish some text into to small of a space");
226				die();
227				$curLine++;
228				$remainingWidth = $width;
229			}
230			
231		}
232		
233		//
234		//	now draw each of the lines
235		//
236		
237		$cury = $y;
238		//if($reallyDraw)
239		//	echo 'soft lines = ' . count($lines) . '<br>';		
240		foreach($lines as $lineKey => $dummyLine)
241		{
242			$thisLine = &$lines[$lineKey];
243			
244			switch($this->alignment)
245			{
246				case 'left':
247					$curx = $x;
248					if($this->bottomIndent && $lineKey > 0)
249						$curx += $this->bottomIndent;
250					break;
251				case 'center':
252					$curx = $x + ( ($width - $thisLine->getWidth()) / 2 );
253					break;
254				case 'right':
255					$curx = $x + ( $width - $thisLine->getWidth() );
256					break;
257				default:
258					trigger_error('invalid alignment specified: ' . $this->alignment);
259					break;
260			}
261			
262			
263			$thisLine->draw($curx, $cury, 0, $reallyDraw);
264			
265			$cury += $thisLine->getHeight(0) + $this->lineSpacing;
266		}
267		
268		
269		$this->doneDrawing = 1;
270		return $cury - $y;
271		*/
272		
273		$cury = $y;
274		foreach(array_keys($lines) as $lineKey)
275		{
276			$thisLine = $lines[$lineKey];
277			$curx = $x;
278			$cury += 12;
279			$thisLine->draw($curx, $cury, NULL, $reallyDraw);
280		}
281		
282		return $cury - $y;
283	}
284	
285	public function drawRenderTree($indentLevel = 0)
286	{
287		$tabs = '';
288		for($i = 0; $i < $indentLevel; $i++)
289			$tabs .= '&nbsp;&nbsp;&nbsp;&nbsp;';
290		
291		//	draw the open tag
292		echo $tabs . '&lt;' . get_class($this) . '&gt;<br>';
293		
294		foreach(array_keys($this->members) as $lineKey)
295		{
296			$this->members[$lineKey]->drawRenderTree($indentLevel + 1);
297		}
298		
299		//	draw the close tag
300		echo $tabs . '&lt;/' . get_class($this) . '&gt;<br>';
301	}
302}