Complex classes like PDF_Japanese often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use PDF_Japanese, and based on these observations, apply Extract Interface, too.
1 | <?php // -*-php-*- |
||
8 | class PDF_Japanese extends PDF { |
||
9 | var $B; |
||
10 | var $I; |
||
11 | var $U; |
||
12 | var $HREF; |
||
13 | var $SJIS_widths = array(' '=>278,'!'=>299,'"'=>353,'#'=>614,'$'=>614,'%'=>721,'&'=>735,'\''=>216, |
||
14 | '('=>323,')'=>323,'*'=>449,'+'=>529,','=>219,'-'=>306,'.'=>219,'/'=>453,'0'=>614,'1'=>614, |
||
15 | '2'=>614,'3'=>614,'4'=>614,'5'=>614,'6'=>614,'7'=>614,'8'=>614,'9'=>614,':'=>219,';'=>219, |
||
16 | '<'=>529,'='=>529,'>'=>529,'?'=>486,'@'=>744,'A'=>646,'B'=>604,'C'=>617,'D'=>681,'E'=>567, |
||
17 | 'F'=>537,'G'=>647,'H'=>738,'I'=>320,'J'=>433,'K'=>637,'L'=>566,'M'=>904,'N'=>710,'O'=>716, |
||
18 | 'P'=>605,'Q'=>716,'R'=>623,'S'=>517,'T'=>601,'U'=>690,'V'=>668,'W'=>990,'X'=>681,'Y'=>634, |
||
19 | 'Z'=>578,'['=>316,'\\'=>614,']'=>316,'^'=>529,'_'=>500,'`'=>387,'a'=>509,'b'=>566,'c'=>478, |
||
20 | 'd'=>565,'e'=>503,'f'=>337,'g'=>549,'h'=>580,'i'=>275,'j'=>266,'k'=>544,'l'=>276,'m'=>854, |
||
21 | 'n'=>579,'o'=>550,'p'=>578,'q'=>566,'r'=>410,'s'=>444,'t'=>340,'u'=>575,'v'=>512,'w'=>760, |
||
22 | 'x'=>503,'y'=>529,'z'=>453,'{'=>326,'|'=>380,'}'=>326,'~'=>387); |
||
23 | |||
24 | function AddCIDFont($family,$style,$name,$cw,$CMap,$registry) |
||
25 | { |
||
26 | $fontkey=strtolower($family).strtoupper($style); |
||
27 | if(isset($this->fonts[$fontkey])) |
||
28 | $this->Error("CID font already added: $family $style"); |
||
29 | $i=count($this->fonts)+1; |
||
30 | $this->fonts[$fontkey]=array('i'=>$i,'type'=>'Type0','name'=>$name,'up'=>-120,'ut'=>40,'cw'=>$cw,'CMap'=>$CMap,'registry'=>$registry); |
||
31 | } |
||
32 | |||
33 | function AddCIDFonts($family,$name,$cw,$CMap,$registry) |
||
34 | { |
||
35 | $this->AddCIDFont($family,'',$name,$cw,$CMap,$registry); |
||
36 | $this->AddCIDFont($family,'B',$name.',Bold',$cw,$CMap,$registry); |
||
37 | $this->AddCIDFont($family,'I',$name.',Italic',$cw,$CMap,$registry); |
||
38 | $this->AddCIDFont($family,'BI',$name.',BoldItalic',$cw,$CMap,$registry); |
||
39 | } |
||
40 | |||
41 | function AddSJISFont($family='SJIS') |
||
42 | { |
||
43 | //Add SJIS font with proportional Latin |
||
44 | $name='KozMinPro-Regular-Acro'; |
||
45 | $cw=$this->SJIS_widths; |
||
46 | $CMap='90msp-RKSJ-H'; |
||
47 | $registry=array('ordering'=>'Japan1','supplement'=>2); |
||
48 | $this->AddCIDFonts($family,$name,$cw,$CMap,$registry); |
||
49 | } |
||
50 | |||
51 | function AddSJIShwFont($family='SJIS-hw') |
||
52 | { |
||
53 | //Add SJIS font with half-width Latin |
||
54 | $name='KozMinPro-Regular-Acro'; |
||
55 | for($i=32;$i<=126;$i++) |
||
56 | $cw[chr($i)]=500; |
||
57 | $CMap='90ms-RKSJ-H'; |
||
58 | $registry=array('ordering'=>'Japan1','supplement'=>2); |
||
59 | $this->AddCIDFonts($family,$name,$cw,$CMap,$registry); |
||
60 | } |
||
61 | |||
62 | function GetStringWidth($s) |
||
63 | { |
||
64 | if($this->CurrentFont['type']=='Type0') |
||
65 | return $this->GetSJISStringWidth($s); |
||
66 | else |
||
67 | return parent::GetStringWidth($s); |
||
68 | } |
||
69 | |||
70 | function GetSJISStringWidth($s) |
||
71 | { |
||
72 | //SJIS version of GetStringWidth() |
||
73 | $l=0; |
||
74 | $cw=&$this->CurrentFont['cw']; |
||
75 | $nb=strlen($s); |
||
76 | $i=0; |
||
77 | while($i<$nb) { |
||
78 | $o=ord($s{$i}); |
||
79 | if($o<128) { |
||
80 | //ASCII |
||
81 | $l+=$cw[$s{$i}]; |
||
82 | $i++; |
||
83 | } |
||
84 | elseif($o>=161 and $o<=223) { |
||
85 | //Half-width katakana |
||
86 | $l+=500; |
||
87 | $i++; |
||
88 | } else { |
||
89 | //Full-width character |
||
90 | $l+=1000; |
||
91 | $i+=2; |
||
92 | } |
||
93 | } |
||
94 | return $l*$this->FontSize/1000; |
||
95 | } |
||
96 | |||
97 | function MultiCell($w,$h,$txt,$border=0,$align='L',$fill=0) |
||
98 | { |
||
99 | if($this->CurrentFont['type']=='Type0') |
||
100 | $this->SJISMultiCell($w,$h,$txt,$border,$align,$fill); |
||
101 | else |
||
102 | parent::MultiCell($w,$h,$txt,$border,$align,$fill); |
||
103 | } |
||
104 | |||
105 | function SJISMultiCell($w,$h,$txt,$border=0,$align='L',$fill=0) |
||
197 | |||
198 | function Write($h,$txt,$link='') |
||
199 | { |
||
200 | if($this->CurrentFont['type']=='Type0') |
||
201 | $this->SJISWrite($h,$txt,$link); |
||
202 | else |
||
203 | parent::Write($h,$txt,$link); |
||
204 | } |
||
205 | |||
206 | function SJISWrite($h,$txt,$link) |
||
207 | { |
||
208 | //SJIS version of Write() |
||
209 | $cw=&$this->CurrentFont['cw']; |
||
210 | $w=$this->w-$this->rMargin-$this->x; |
||
211 | $wmax=($w-2*$this->cMargin)*1000/$this->FontSize; |
||
212 | $s=str_replace("\r",'',$txt); |
||
213 | $nb=strlen($s); |
||
214 | $sep=-1; |
||
215 | $i=0; |
||
216 | $j=0; |
||
217 | $l=0; |
||
218 | $nl=1; |
||
219 | while($i<$nb) { |
||
220 | //Get next character |
||
221 | $c=$s{$i}; |
||
222 | $o=ord($c); |
||
223 | if($o==10) { |
||
224 | //Explicit line break |
||
225 | $this->Cell($w,$h,substr($s,$j,$i-$j),0,2,'',0,$link); |
||
226 | $i++; |
||
227 | $sep=-1; |
||
228 | $j=$i; |
||
229 | $l=0; |
||
230 | if($nl==1) { |
||
231 | //Go to left margin |
||
232 | $this->x=$this->lMargin; |
||
233 | $w=$this->w-$this->rMargin-$this->x; |
||
234 | $wmax=($w-2*$this->cMargin)*1000/$this->FontSize; |
||
235 | } |
||
236 | $nl++; |
||
237 | continue; |
||
238 | } |
||
239 | if($o<128) { |
||
240 | //ASCII |
||
241 | $l+=$cw[$c]; |
||
242 | $n=1; |
||
243 | if($o==32) |
||
244 | $sep=$i; |
||
245 | } elseif($o>=161 and $o<=223) { |
||
246 | //Half-width katakana |
||
247 | $l+=500; |
||
248 | $n=1; |
||
249 | $sep=$i; |
||
250 | } else { |
||
251 | //Full-width character |
||
252 | $l+=1000; |
||
253 | $n=2; |
||
254 | $sep=$i; |
||
255 | } |
||
256 | if($l>$wmax) { |
||
257 | //Automatic line break |
||
258 | if($sep==-1 or $i==$j) { |
||
259 | if($this->x>$this->lMargin) { |
||
260 | //Move to next line |
||
261 | $this->x=$this->lMargin; |
||
262 | $this->y+=$h; |
||
263 | $w=$this->w-$this->rMargin-$this->x; |
||
264 | $wmax=($w-2*$this->cMargin)*1000/$this->FontSize; |
||
265 | $i+=$n; |
||
266 | $nl++; |
||
267 | continue; |
||
268 | } |
||
269 | if($i==$j) |
||
270 | $i+=$n; |
||
271 | $this->Cell($w,$h,substr($s,$j,$i-$j),0,2,'',0,$link); |
||
272 | } else { |
||
273 | $this->Cell($w,$h,substr($s,$j,$sep-$j),0,2,'',0,$link); |
||
274 | $i=($s[$sep]==' ') ? $sep+1 : $sep; |
||
275 | } |
||
276 | $sep=-1; |
||
277 | $j=$i; |
||
278 | $l=0; |
||
279 | if($nl==1) { |
||
280 | $this->x=$this->lMargin; |
||
281 | $w=$this->w-$this->rMargin-$this->x; |
||
282 | $wmax=($w-2*$this->cMargin)*1000/$this->FontSize; |
||
283 | } |
||
284 | $nl++; |
||
285 | } else { |
||
286 | $i+=$n; |
||
287 | if($o>=128) |
||
288 | $sep=$i; |
||
289 | } |
||
290 | } |
||
291 | //Last chunk |
||
292 | if($i!=$j) |
||
293 | $this->Cell($l/1000*$this->FontSize,$h,substr($s,$j,$i-$j),0,0,'',0,$link); |
||
294 | } |
||
295 | |||
296 | function _putfonts() |
||
383 | |||
384 | function _putType0($font) |
||
385 | { |
||
386 | //Type0 |
||
387 | $this->_out('/Subtype /Type0'); |
||
388 | $this->_out('/BaseFont /'.$font['name'].'-'.$font['CMap']); |
||
389 | $this->_out('/Encoding /'.$font['CMap']); |
||
390 | $this->_out('/DescendantFonts ['.($this->n+1).' 0 R]'); |
||
391 | $this->_out('>>'); |
||
392 | $this->_out('endobj'); |
||
420 | } |
||
421 | |||
430 |