手机电子书UMD数据格式实现代码(C#版)

简介: 原文地址:http://blog.joycode.com/uestc95/archive/2008/06/19/115155.aspx    UMD格式是国内手机阅读中使用较多的一种格式,但其公司却并没有将UMD数据格式公开,但是却用另外一种方式将其公开,你去访问一下他们的站点然后下载他的制作工具就知道。

原文地址:http://blog.joycode.com/uestc95/archive/2008/06/19/115155.aspx 

  UMD格式是国内手机阅读中使用较多的一种格式,但其公司却并没有将UMD数据格式公开,但是却用另外一种方式将其公开,你去访问一下他们的站点然后下载他的制作工具就知道。

下面的是文本的UMD相关处理代码,图形的下一篇post出来

namespace  Ikari
{
    
using  ICSharpCode.SharpZipLib.Zip.Compression;
    
using  System;
    
using  System.Collections;
    
using  System.IO;
    
using  System.Reflection;
    
using  System.Runtime.InteropServices;
    
using  System.Text;
    
using  System.Windows.Forms;

    
public   class  UMD_GENEGINE
    {
        
private   const   int  A_32K_BYTE  =   0x8000 ;
        
private   byte  ACTUAL_WIDTH_S60_HORI  =   0xcc ;
        
private   byte  ACTUAL_WIDTH_S60_VERT  =   0xac ;
        
private   byte  ACTUAL_WIDTH_SP  =   0xa6 ;
        
private   const   uint  BASE_REFN_CHAP_OFF  =   0x3000 ;
        
private   const   uint  BASE_REFN_CHAP_STR  =   0x4000 ;
        
private   const   uint  BASE_REFN_CONTENT  =   0x2000 ;
        
private   const   uint  BASE_REFN_COVER  =   0x1000 ;
        
private   const   uint  BASE_REFN_PAGE_OFFSET  =   0x7000 ;
        
private   const   string  BEYOND_END_FLAG  =   " /0 " ;
        
private   const   int  BYTE_LEN  =   1 ;
        
private   const   byte  COVER_TYPE_BMP  =   0 ;
        
private   const   byte  COVER_TYPE_GIF  =   2 ;
        
private   const   byte  COVER_TYPE_JPG  =   1 ;
        
private   const   int  CURR_VERSION  =   1 ;
        
private   const   short  DCTS_CMD_ID_AUTHOR  =   3 ;
        
private   const   short  DCTS_CMD_ID_CDS_KEY  =   240 ;
        
private   const   short  DCTS_CMD_ID_CHAP_OFF  =   0x83 ;
        
private   const   short  DCTS_CMD_ID_CHAP_STR  =   0x84 ;
        
private   const   short  DCTS_CMD_ID_CONTENT_ID  =   10 ;
        
private   const   short  DCTS_CMD_ID_COVER_PAGE  =   130 ;
        
private   const   short  DCTS_CMD_ID_DAY  =   6 ;
        
private   const   short  DCTS_CMD_ID_FILE_LENGTH  =   11 ;
        
private   const   short  DCTS_CMD_ID_FIXED_LEN  =   12 ;
        
private   const   short  DCTS_CMD_ID_GENDER  =   7 ;
        
private   const   short  DCTS_CMD_ID_LICENSE_KEY  =   0xf1 ;
        
private   const   short  DCTS_CMD_ID_MONTH  =   5 ;
        
private   const   short  DCTS_CMD_ID_PAGE_OFFSET  =   0x87 ;
        
private   const   short  DCTS_CMD_ID_PUBLISHER  =   8 ;
        
private   const   short  DCTS_CMD_ID_REF_CONTENT  =   0x81 ;
        
private   const   short  DCTS_CMD_ID_TITLE  =   2 ;
        
private   const   short  DCTS_CMD_ID_VENDOR  =   9 ;
        
private   const   short  DCTS_CMD_ID_VERSION  =   1 ;
        
private   const   short  DCTS_CMD_ID_YEAR  =   4 ;
        
private   const   byte  FIXED_LINE_PER_PAGE_S60  =   50 ;
        
private   const   byte  FIXED_LINE_PER_PAGE_SP  =   0x19 ;
        
private   string  iAuthor;
        
private   byte [] ibContent;
        
private   int [] iChapOff;
        
private  ArrayList iChapStr  =   new  ArrayList();
        
private  ArrayList iChapter  =   new  ArrayList();
        
private   int  iCID;
        
private   string  iContent;
        
private   string  iCoverFile;
        
private   string  iDay;
        
private   string  iGender;
        
private   string  iMonth;
        
private   const   int  INT_LEN  =   4 ;
        
private   short  iPGKSeed  =   0 ;
        
private   string  iPublisher;
        
private   string  iSaveTo;
        
private   string  iTitle;
        
private   int  iTotalen;
        
private   string  iVendor;
        
private  ArrayList iWidthData_S60  =   new  ArrayList();
        
private  ArrayList iWidthData_SP  =   new  ArrayList();
        
private   string  iYear;
        
private   byte [][] iZippedSeg;
        
private   const   string  KEY_CODE_TAB  =   " /t " ;
        
private   const   byte  S60_FONT_SIZE_BIG  =   0x10 ;
        
private   const   byte  S60_FONT_SIZE_SMALL  =   12 ;
        
private   const   byte  SEREIS60_FONTS_COUNT  =   2 ;
        
private   const   int  SHORT_LEN  =   2 ;
        
private   const   byte  SP_FONT_SIZE_10  =   10 ;
        
private   const   byte  SP_FONT_SIZE_MAX  =   0x10 ;
        
private   const   byte  SP_FONT_SIZE_MIN  =   6 ;
        
private   const   string  SYMBIAN_RETURN  =   " /u2029 " ;
        
private   const   string  SYMBIAN_SPACE  =   "   " ;
        
private   const   byte  UMD_DCTD_HEAD_LEN  =   9 ;
        
private   const   byte  UMD_DCTS_HEAD_LEN  =   5 ;
        
private   const   int  UMD_FREE_CID_MIN  =   0x5f5e100 ;
        
private   const   int  UMD_FREE_PGK_SEED_MIN  =   0x400 ;
        
private   const   int  UMD_LICENSEKEY_LEN  =   0x10 ;
        
private   const   int  UMD_MAX_BOOKMARK_STR_LEN  =   40 ;
        
private   const   byte  UMD_PLATFORM_ID_NONE  =   0 ;
        
private   const   byte  UMD_PLATFORM_ID_S60  =   1 ;
        
private   const   byte  UMD_PLATFORM_ID_SP  =   5 ;
        
private   const   int  UMD_SEGMENT_LENGTH  =   0x8000 ;
        
private   const   byte  VER_PKG_LEN  =   3 ;
        
private   const   string  WINDOWS_RETURN  =   " /r/n " ;
        
private   const   int  ZIP_LEVEL  =   9 ;

        
private   byte  CharWidth_S60( string  Char,  byte  pFontSize)
        {
            
ushort  num  =  Char[ 0 ];
            
for  ( int  i  =   0 ; i  <   this .iWidthData_S60.Count; i ++ )
            {
                SWidthData data 
=  (SWidthData)  this .iWidthData_S60[i];
                
if  (((data.FontSize  ==  pFontSize)  &&  (num  >=  data.rngFrom))  &&  (num  <=  data.rngTo))
                {
                    
if  (data.vCount  ==   1 )
                    {
                        
return  data.Value[ 0 ];
                    }
                    
return  data.Value[num  -  data.rngFrom];
                }
            }
            
return  pFontSize;
        }

        
private   byte  CharWidth_SP( string  Char,  byte  pFontSize)
        {
            
ushort  num  =  Char[ 0 ];
            
for  ( int  i  =   0 ; i  <   this .iWidthData_SP.Count; i ++ )
            {
                SWidthData data 
=  (SWidthData)  this .iWidthData_SP[i];
                
if  (((data.FontSize  ==  pFontSize)  &&  (num  >=  data.rngFrom))  &&  (num  <=  data.rngTo))
                {
                    
if  (data.vCount  ==   1 )
                    {
                        
return  data.Value[ 0 ];
                    }
                    
return  data.Value[num  -  data.rngFrom];
                }
            }
            
return  pFontSize;
        }

        
private   bool  GetPageOffsetS60( byte  size,  uint  actual_width,  ref  ProgressBar pbar,  out   uint [] result)
        {
            ArrayList pPageoff 
=   new  ArrayList();
            
if  ((size  !=   0x10 &&  (size  !=   12 ))
            {
                result 
=   new   uint [ 0 ];
                
return   false ;
            }
            
this .GetWidthData_S60();
            pPageoff.Add(
0 );
            
int  num  =  pbar.Value;
            
while  ((( int ) pPageoff[pPageoff.Count  -   1 ])  <   this .iContent.Length)
            {
                
this .ParseOnePage(( uint ) (pPageoff.Count  -   1 ), size, actual_width,  ref  pPageoff,  1 );
                pbar.Value 
=  num  +  (( int ) (( uint ) pPageoff[pPageoff.Count  -   1 ]));
            }
            result 
=   new   uint [pPageoff.Count];
            
for  ( int  i  =   0 ; i  <  pPageoff.Count; i ++ )
            {
                result[i] 
=  (( uint ) pPageoff[i])  *   2 ;
            }
            
return   true ;
        }

        
private   bool  GetPageOffsetSP( byte  size,  uint  actual_width,  ref  ProgressBar pbar,  out   uint [] result)
        {
            ArrayList pPageoff 
=   new  ArrayList();
            
if  ((size  <   6 ||  (size  >   0x10 ))
            {
                result 
=   new   uint [ 0 ];
                
return   false ;
            }
            
this .GetWidthData_SP();
            pPageoff.Add(
0 );
            
int  num  =  pbar.Value;
            
while  ((( uint ) pPageoff[pPageoff.Count  -   1 ])  <   this .iContent.Length)
            {
                
this .ParseOnePage(( uint ) (pPageoff.Count  -   1 ), size, actual_width,  ref  pPageoff,  5 );
                
if  ((num  +  (( int ) (( uint ) pPageoff[pPageoff.Count  -   1 ])))  <  pbar.Maximum)
                {
                    pbar.Value 
=  num  +  (( int ) (( uint ) pPageoff[pPageoff.Count  -   1 ]));
                }
            }
            result 
=   new   uint [pPageoff.Count];
            
for  ( int  i  =   0 ; i  <  pPageoff.Count; i ++ )
            {
                result[i] 
=  ( uint ) pPageoff[i];
            }
            
return   true ;
        }

        
private   void  GetWidthData_S60()
        {
            
this .iWidthData_S60.Clear();
            
for  ( int  i  =   0 ; i  <   2 ; i ++ )
            {
                
string  path  =   "" ;
                
switch  (i)
                {
                    
case   0 :
                        path 
=  Path.GetDirectoryName(Assembly.GetExecutingAssembly().CodeBase.Remove( 0 8 ))  +   @" /FontWidthData/S60CHS.S16.wdt " ;
                        
break ;

                    
case   1 :
                        path 
=  Path.GetDirectoryName(Assembly.GetExecutingAssembly().CodeBase.Remove( 0 8 ))  +   @" /FontWidthData/S60CHS.S12.wdt " ;
                        
break ;
                }
                
if  (File.Exists(path))
                {
                    FileStream input 
=   new  FileStream(path, FileMode.Open, FileAccess.Read);
                    BinaryReader reader 
=   new  BinaryReader(input);
                    
while  (reader.BaseStream.Position  <  reader.BaseStream.Length)
                    {
                        
ushort  num2  =  reader.ReadUInt16();
                        
ushort  num3  =  reader.ReadUInt16();
                        
uint  num4  =  reader.ReadUInt16();
                        
byte [] buffer  =   new   byte [num4];
                        
for  ( uint  j  =   0 ; j  <  num4; j ++ )
                        {
                            buffer[j] 
=  reader.ReadByte();
                        }
                        SWidthData data 
=   new  SWidthData();
                        
switch  (i)
                        {
                            
case   0 :
                                data.FontSize 
=   0x10 ;
                                
break ;

                            
case   1 :
                                data.FontSize 
=   12 ;
                                
break ;
                        }
                        data.rngFrom 
=  num2;
                        data.rngTo 
=  num3;
                        data.vCount 
=  num4;
                        data.Value 
=  buffer;
                        
this .iWidthData_S60.Add(data);
                    }
                    reader.Close();
                    input.Close();
                }
            }
        }

        
private   void  GetWidthData_SP()
        {
            
this .iWidthData_SP.Clear();
            
for  ( int  i  =   0x10 ; i  <   0x11 ; i ++ )
            {
                
string  path  =  (Assembly.GetExecutingAssembly().CodeBase.Remove( 0 8 +   @" /FontWidthData/sunfon.s " +  i.ToString()  +   " .wdt " ;
                
if  (File.Exists(path))
                {
                    FileStream input 
=   new  FileStream(path, FileMode.Open, FileAccess.Read);
                    BinaryReader reader 
=   new  BinaryReader(input);
                    
while  (reader.BaseStream.Position  <  reader.BaseStream.Length)
                    {
                        
ushort  num2  =  reader.ReadUInt16();
                        
ushort  num3  =  reader.ReadUInt16();
                        
uint  num4  =  reader.ReadUInt16();
                        
byte [] buffer  =   new   byte [num4];
                        
for  ( uint  j  =   0 ; j  <  num4; j ++ )
                        {
                            buffer[j] 
=  reader.ReadByte();
                        }
                        SWidthData data 
=   new  SWidthData();
                        data.FontSize 
=  ( byte ) i;
                        data.rngFrom 
=  num2;
                        data.rngTo 
=  num3;
                        data.vCount 
=  num4;
                        data.Value 
=  buffer;
                        
this .iWidthData_SP.Add(data);
                    }
                    reader.Close();
                    input.Close();
                }
            }
        }

        
public   bool  Initialize( string  aTitle,  string  aAuthor,  string  aYear,  string  aMonth,  string  aDay,  string  aGender,  string  aPublisher,  string  aVendor,  string  aCoverFile,  int  aContentID,  string  aSaveTo,  ref  ArrayList aChapter,  ref  ArrayList aChapStr,  out   string  aResult)
        {
            aResult 
=   " true " ;
            
if  (aTitle.Length  <=   0 )
            {
                aResult 
=   " 标题不能为空 " ;
                
return   false ;
            }
            
if  (aAuthor.Length  <=   0 )
            {
                aResult 
=   " 作者不能为空 " ;
                
return   false ;
            }
            
if  (((aYear.Length  >   4 ||  (aMonth.Length  >   2 ))  ||  (aDay.Length  >   2 ))
            {
                aResult 
=   " 日期非法 " ;
                
return   false ;
            }
            
if  (aChapter.Count  <=   0 )
            {
                aResult 
=   " 内容数量不能小于0 " ;
                
return   false ;
            }
            
if  (aChapter.Count  !=  aChapStr.Count)
            {
                aResult 
=   " 章节标题数量和章节内容数量不符 " ;
                
return   false ;
            }
            
if  ( ! Directory.Exists(aSaveTo))
            {
                aResult 
=   " 保存文件的路径不存在 " ;
                
return   false ;
            }
            
this .iTitle  =  aTitle;
            
this .iAuthor  =  aAuthor;
            
this .iYear  =  aYear;
            
this .iMonth  =  aMonth;
            
this .iDay  =  aDay;
            
this .iGender  =  aGender;
            
this .iPublisher  =  aPublisher;
            
this .iVendor  =  aVendor;
            
this .iCID  =  aContentID;
            
this .iCoverFile  =  aCoverFile;
            
this .iSaveTo  =  aSaveTo;
            File.Copy(
this .iCoverFile  +   " .tmp " this .iSaveTo  +   @" / "   +   this .iTitle  +   " .jpg " );
            
for  ( int  i  =   0 ; i  <  aChapter.Count; i ++ )
            {
                
this .iChapter.Add((( string ) aChapter[i])  +   " /u2029 " );
                
this .iChapStr.Add(( string ) aChapStr[i]);
            }
            
this .iChapOff  =   new   int [ this .iChapter.Count];
            
return   true ;
        }

        
public   bool  Make( ref  ProgressBar pbar,  out   string  result)
        {
            
uint [] numArray2;
            
this .Prepare();
            Random random 
=   new  Random();
            
uint  num  =   0 ;
            
if  ( this .iSaveTo.EndsWith( @" / " ))
            {
                
this .iSaveTo.Remove( this .iSaveTo.Length  -   1 1 );
            }
            
string  path  =   this .iSaveTo  +   @" / "   +   this .iTitle  +   " .umd " ;
            
if  (File.Exists(path))
            {
                
if  (MessageBox.Show( " 您要保存的文件已经存在,是否覆盖? " " mBook制作工具 版本:1.0 " , MessageBoxButtons.YesNo, MessageBoxIcon.Question)  !=  DialogResult.Yes)
                {
                    result 
=   " 生成文件操作被用户取消 " ;
                    
return   false ;
                }
                File.Delete(path);
            }
            FileStream output 
=   new  FileStream(path, FileMode.OpenOrCreate, FileAccess.Write);
            BinaryWriter writer 
=   new  BinaryWriter(output);
            
byte  num1  =  Encoding.Unicode.GetBytes(( string this .iChapter[ 0 ])[ 0 ];
            writer.Write((
uint 0xde9a9b89 );
            writer.Write(
' # ' );
            writer.Write((
short 1 );
            writer.Write((
byte 0 );
            writer.Write((
byte 8 );
            writer.Write((
byte 1 );
            writer.Write(
this .iPGKSeed);
            writer.Write(
' # ' );
            writer.Write((
short 2 );
            writer.Write((
byte 0 );
            writer.Write((
byte ) ( 5   +  ( this .iTitle.Length  *   2 )));
            writer.Write(Encoding.Unicode.GetBytes(
this .iTitle));
            writer.Write(
' # ' );
            writer.Write((
short 3 );
            writer.Write((
byte 0 );
            writer.Write((
byte ) ( 5   +  ( this .iAuthor.Length  *   2 )));
            writer.Write(Encoding.Unicode.GetBytes(
this .iAuthor));
            
if  ( this .iYear.Length  >   0 )
            {
                writer.Write(
' # ' );
                writer.Write((
short 4 );
                writer.Write((
byte 0 );
                writer.Write((
byte ) ( 5   +  ( this .iYear.Length  *   2 )));
                writer.Write(Encoding.Unicode.GetBytes(
this .iYear));
            }
            
if  ( this .iMonth.Length  >   0 )
            {
                writer.Write(
' # ' );
                writer.Write((
short 5 );
                writer.Write((
byte 0 );
                writer.Write((
byte ) ( 5   +  ( this .iMonth.Length  *   2 )));
                writer.Write(Encoding.Unicode.GetBytes(
this .iMonth));
            }
            
if  ( this .iDay.Length  >   0 )
            {
                writer.Write(
' # ' );
                writer.Write((
short 6 );
                writer.Write((
byte 0 );
                writer.Write((
byte ) ( 5   +  ( this .iDay.Length  *   2 )));
                writer.Write(Encoding.Unicode.GetBytes(
this .iDay));
            }
            
if  ( this .iGender.Length  >   0 )
            {
                writer.Write(
' # ' );
                writer.Write((
short 7 );
                writer.Write((
byte 0 );
                writer.Write((
byte ) ( 5   +  ( this .iGender.Length  *   2 )));
                writer.Write(Encoding.Unicode.GetBytes(
this .iGender));
            }
            
if  ( this .iPublisher.Length  >   0 )
            {
                writer.Write(
' # ' );
                writer.Write((
short 8 );
                writer.Write((
byte 0 );
                writer.Write((
byte ) ( 5   +  ( this .iPublisher.Length  *   2 )));
                writer.Write(Encoding.Unicode.GetBytes(
this .iPublisher));
            }
            
if  ( this .iVendor.Length  >   0 )
            {
                writer.Write(
' # ' );
                writer.Write((
short 9 );
                writer.Write((
byte 0 );
                writer.Write((
byte ) ( 5   +  ( this .iVendor.Length  *   2 )));
                writer.Write(Encoding.Unicode.GetBytes(
this .iVendor));
            }
            writer.Write(
' # ' );
            writer.Write((
short 11 );
            writer.Write((
byte 0 );
            writer.Write((
byte 9 );
            writer.Write(
this .ibContent.Length);
            num 
=  ( uint ) ( 0x3000L   +  random.Next( 0xfff ));
            writer.Write(
' # ' );
            writer.Write((
short 0x83 );
            writer.Write((
byte 1 );
            writer.Write((
byte 9 );
            writer.Write(num);
            writer.Write(
' $ ' );
            writer.Write(num);
            writer.Write((
uint ) ( 9   +  ( this .iChapOff.Length  *   4 )));
            
foreach  ( int  num2  in   this .iChapOff)
            {
                writer.Write(num2);
            }
            num 
=  ( uint ) ( 0x4000L   +  random.Next( 0xfff ));
            writer.Write(
' # ' );
            writer.Write((
short 0x84 );
            writer.Write((
byte 1 );
            writer.Write((
byte 9 );
            writer.Write(num);
            
int  num3  =   0 ;
            
foreach  ( object  obj2  in   this .iChapStr)
            {
                num3 
+=  ((( string ) obj2).Length  *   2 +   1 ;
            }
            writer.Write(
' $ ' );
            writer.Write(num);
            writer.Write((
uint ) ( 9   +  num3));
            
foreach  ( object  obj3  in   this .iChapStr)
            {
                writer.Write((
byte ) ((( string ) obj3).Length  *   2 ));
                writer.Write(Encoding.Unicode.GetBytes((
string ) obj3));
            }
            
int  num4  =   0 ;
            
int  num5  =   0 ;
            
uint [] numArray  =   new   uint [ this .iZippedSeg.Length];
            
if  ( this .iZippedSeg.Length  >   1 )
            {
                num4 
=  random.Next( 0 this .iZippedSeg.Length  -   1 );
                num5 
=  random.Next( 0 this .iZippedSeg.Length  -   1 );
            }
            
for  ( int  i  =   0 ; i  <   this .iZippedSeg.Length; i ++ )
            {
                numArray[i] 
=  ( uint ) (random.Next( 1 0xfffffff *   - 1 );
                writer.Write(
' $ ' );
                writer.Write(numArray[i]);
                writer.Write((
uint ) ( 9   +   this .iZippedSeg[i].Length));
                writer.Write(
this .iZippedSeg[i]);
                
if  (i  ==  num4)
                {
                    writer.Write(
' # ' );
                    writer.Write((
short 0xf1 );
                    writer.Write((
byte 0 );
                    writer.Write((
byte 0x15 );
                    writer.Write(Encoding.ASCII.GetBytes(
" /0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0 " ));
                }
                
if  (i  ==  num5)
                {
                    writer.Write(
' # ' );
                    writer.Write((
short 10 );
                    writer.Write((
byte 0 );
                    writer.Write((
byte 9 );
                    writer.Write(
this .iCID);
                }
            }
            num 
=  ( uint ) ( 0x2000L   +  random.Next( 0xfff ));
            writer.Write(
' # ' );
            writer.Write((
short 0x81 );
            writer.Write((
byte 1 );
            writer.Write((
byte 9 );
            writer.Write(num);
            writer.Write(
' $ ' );
            writer.Write(num);
            writer.Write((
uint ) ( 9   +  (numArray.Length  *   4 )));
            
foreach  ( uint  num7  in  numArray)
            {
                writer.Write(num7);
            }
            
if  (File.Exists( this .iCoverFile))
            {
                FileStream stream2 
=   new  FileStream( this .iCoverFile  +   " .tmp " , FileMode.Open);
                
byte [] buffer  =   new   byte [stream2.Length];
                stream2.Read(buffer, 
0 , ( int ) stream2.Length);
                stream2.Close();
                num 
=  ( uint ) ( 0x1000L   +  random.Next( 0xfff ));
                writer.Write(
' # ' );
                writer.Write((
short 130 );
                writer.Write((
byte 1 );
                writer.Write((
byte 10 );
                writer.Write((
byte 1 );
                writer.Write(num);
                writer.Write(
' $ ' );
                writer.Write(num);
                writer.Write((
uint ) ( 9   +  buffer.Length));
                writer.Write(buffer);
            }
            pbar.Maximum 
=   this .iContent.Length  *   5 ;
            pbar.Value 
=   0 ;
            
this .GetPageOffsetS60( 0x10 this .ACTUAL_WIDTH_S60_HORI,  ref  pbar,  out  numArray2);
            
this .WritePageOffset( 0x10 , ( byte ) ( this .ACTUAL_WIDTH_S60_HORI  +   4 ),  ref  numArray2,  ref  writer,  1 );
            numArray2.Initialize();
            
this .GetPageOffsetS60( 0x10 this .ACTUAL_WIDTH_S60_VERT,  ref  pbar,  out  numArray2);
            
this .WritePageOffset( 0x10 , ( byte ) ( this .ACTUAL_WIDTH_S60_VERT  +   4 ),  ref  numArray2,  ref  writer,  1 );
            numArray2.Initialize();
            
this .GetPageOffsetS60( 12 this .ACTUAL_WIDTH_S60_HORI,  ref  pbar,  out  numArray2);
            
this .WritePageOffset( 12 , ( byte ) ( this .ACTUAL_WIDTH_S60_HORI  +   4 ),  ref  numArray2,  ref  writer,  1 );
            numArray2.Initialize();
            
this .GetPageOffsetS60( 12 this .ACTUAL_WIDTH_S60_VERT,  ref  pbar,  out  numArray2);
            
this .WritePageOffset( 12 , ( byte ) ( this .ACTUAL_WIDTH_S60_VERT  +   4 ),  ref  numArray2,  ref  writer,  1 );
            numArray2.Initialize();
            
this .GetPageOffsetSP( 10 this .ACTUAL_WIDTH_SP,  ref  pbar,  out  numArray2);
            
this .WritePageOffset( 10 this .ACTUAL_WIDTH_SP,  ref  numArray2,  ref  writer,  5 );
            writer.Write(
' # ' );
            writer.Write((
short 12 );
            writer.Write((
byte 1 );
            writer.Write((
byte 9 );
            writer.Write((
uint ) ((( uint ) writer.BaseStream.Position)  +   4 ));
            writer.Close();
            output.Close();
            result 
=   " true " ;
            
return   true ;
        }

        
private   void  ParseOnePage( uint  pPageNumber,  byte  pFontSize,  uint  pScreenWidth,  ref  ArrayList pPageoff,  byte  PID)
        {
            
if  (pPageNumber  <  pPageoff.Count)
            {
                
string  str  =   "" ;
                
int  num  =   0 ;
                
uint  num2  =  ( uint ) pPageoff[( int ) pPageNumber];
                ArrayList list 
=   new  ArrayList();
                
byte  num3  =   0 ;
                
if  (PID  ==   1 )
                {
                    num3 
=   50 ;
                }
                
if  (PID  ==   5 )
                {
                    num3 
=   0x19 ;
                }
                
for  ( byte  i  =   0 ; i  <  num3; i  =  ( byte ) (i  +   1 ))
                {
                    str 
=  str.Remove( 0 , str.Length);
                    
string  str2  =   "" ;
                    
byte  num5  =   0 ;
                Label_0061:
                    
if  (num2  <   this .iContent.Length)
                    {
                        str2 
=   this .iContent.Substring(( int ) num2,  1 );
                    }
                    
else
                    {
                        str2 
=   " /0 " ;
                    }
                    
switch  (str2)
                    {
                        
case   " /t " :
                        
case   " /0 " :
                            str2 
=   "   " ;
                            
break ;
                    }
                    
byte  num6  =   this .CharWidth_S60(str2, pFontSize);
                    
if  (str2  ==   " /u2029 " )
                    {
                        num6 
=   0 ;
                    }
                    
if  ((num6  +  num5)  <=  pScreenWidth)
                    {
                        num5 
=  ( byte ) (num5  +  num6);
                        num2
++ ;
                        
if  ( ! (str2  ==   " /u2029 " ))
                        {
                            str 
=  str  +  str2;
                            
goto  Label_0061;
                        }
                    }
                    
if  (str2  !=   " /u2029 " )
                    {
                        list.Add(str.Length);
                    }
                    
else
                    {
                        list.Add(str.Length 
+   1 );
                    }
                    num 
+=  ( int ) list[i];
                    
if  (i  ==  (( byte ) (num3  -   1 )))
                    {
                        
if  ((num2  <   this .iContent.Length)  &&  (num2  >  (( uint ) pPageoff[pPageoff.Count  -   1 ])))
                        {
                            pPageoff.Add(((
uint ) pPageoff[pPageoff.Count  -   1 ])  +  (( uint ) num));
                        }
                        
if  (num2  >=   this .iContent.Length)
                        {
                            pPageoff.Add((
uint this .iContent.Length);
                        }
                    }
                }
            }
        }

        
private   void  Prepare()
        {
            Random random 
=   new  Random();
            
this .iPGKSeed  =  ( short ) (random.Next( 0x401 0x7fff %   0xffff );
            
this .iTotalen  =   0 ;
            
for  ( int  i  =   0 ; i  <   this .iChapter.Count; i ++ )
            {
                
this .iChapter[i]  =  (( string this .iChapter[i]).Replace( " /r/n " " /u2029 " );
                
this .iContent  =   this .iContent  +  (( string this .iChapter[i]);
                
this .iChapOff[i]  =   this .iTotalen;
                
this .iTotalen  +=  (( string this .iChapter[i]).Length  *   2 ;
            }
            
this .ibContent  =   new   byte [ this .iTotalen];
            
int  index  =   0 ;
            
for  ( int  j  =   0 ; j  <   this .iChapter.Count; j ++ )
            {
                
byte [] bytes  =   new   byte [(( string this .iChapter[j]).Length  *   2 ];
                bytes 
=  Encoding.Unicode.GetBytes(( string this .iChapter[j]);
                bytes.CopyTo(
this .ibContent, index);
                index 
+=  bytes.Length;
            }
            
int  num4  =   0 ;
            
if  (( this .iTotalen  %   0x8000 ==   0 )
            {
                num4 
=   this .iTotalen  /   0x8000 ;
            }
            
else
            {
                num4 
=  ( this .iTotalen  /   0x8000 +   1 ;
            }
            
this .iZippedSeg  =   new   byte [num4][];
            
byte [] input  =   new   byte [ 0x8000 ];
            
int  num5  =   0 ;
            
int  num6  =   0 ;
            
for  ( int  k  =   0 ; k  <   this .ibContent.Length; k ++ )
            {
                input[num5] 
=   this .ibContent[k];
                
if  ((num5  ==   0x7fff ||  (k  ==  ( this .ibContent.Length  -   1 )))
                {
                    
byte [] output  =   new   byte [ 0x8000 ];
                    num5 
=   0 ;
                    Deflater deflater 
=   new  Deflater(Deflater.BEST_COMPRESSION,  false );
                    
if  (deflater.IsNeedingInput)
                    {
                        deflater.SetInput(input, 
0 , input.Length);
                    }
                    deflater.Finish();
                    deflater.Deflate(output);
                    
this .iZippedSeg[num6]  =   new   byte [deflater.TotalOut];
                    Deflater deflater2 
=   new  Deflater(Deflater.BEST_COMPRESSION,  false );
                    
if  (deflater2.IsNeedingInput)
                    {
                        deflater2.SetInput(input, 
0 , input.Length);
                    }
                    deflater2.Finish();
                    deflater2.Deflate(
this .iZippedSeg[num6]);
                    num6
++ ;
                    input 
=  Encoding.Unicode.GetBytes( "" );
                    input 
=   new   byte [ 0x8000 ];
                }
                
else
                {
                    num5
++ ;
                }
            }
        }

        
private   void  WritePageOffset( byte  fontSize,  byte  screenWidth,  ref   uint [] data,  ref  BinaryWriter writer,  byte  PID)
        {
            Random random 
=   new  Random();
            
uint  num  =  ( uint ) ( 0x7000L   +  random.Next( 0xfff ));
            writer.Write(
' # ' );
            writer.Write((
short 0x87 );
            writer.Write(PID);
            writer.Write((
byte 11 );
            writer.Write(fontSize);
            writer.Write(screenWidth);
            writer.Write(num);
            writer.Write(
' $ ' );
            writer.Write(num);
            writer.Write((
uint ) ( 9   +  (data.Length  *   4 )));
            
foreach  ( uint  num2  in  data)
            {
                writer.Write(num2);
            }
        }

        [StructLayout(LayoutKind.Sequential)]
        
private   struct  SWidthData
        {
            
public   byte  FontSize;
            
public   ushort  rngFrom;
            
public   ushort  rngTo;
            
public   uint  vCount;
            
public   byte [] Value;
        }
    }
}


国内最棒的Google Android技术社区(eoeandroid),欢迎访问!

《银河系列原创教程》发布

《Java Web开发速学宝典》出版,欢迎定购

目录
相关文章
|
8月前
|
JavaScript Java 测试技术
基于ssm+vue.js+uniapp小程序的怀旧唱片售卖系统附带文章和源代码设计说明文档ppt
基于ssm+vue.js+uniapp小程序的怀旧唱片售卖系统附带文章和源代码设计说明文档ppt
49 3
|
8月前
|
JavaScript Java 测试技术
Java项目基于ssm+vue.js的网上手机销售系统附带文章和源代码设计说明文档ppt
Java项目基于ssm+vue.js的网上手机销售系统附带文章和源代码设计说明文档ppt
77 0
|
8月前
|
JavaScript Java 测试技术
基于ssm+vue.js+uniapp小程序的视频播放器附带文章和源代码设计说明文档ppt
基于ssm+vue.js+uniapp小程序的视频播放器附带文章和源代码设计说明文档ppt
59 3
|
3月前
|
移动开发 数据可视化 JavaScript
DIY官网可视化设计导出UNIAPP源码
DIY官网可视化设计导出UNIAPP源码
47 2
|
8月前
|
JavaScript Java 测试技术
基于小程序的小说阅读器+springboot+vue.js附带文章和源代码设计说明文档ppt
基于小程序的小说阅读器+springboot+vue.js附带文章和源代码设计说明文档ppt
79 0
|
8月前
|
JavaScript Java 测试技术
基于ssm+vue.js+uniapp小程序的手机官网附带文章和源代码设计说明文档ppt
基于ssm+vue.js+uniapp小程序的手机官网附带文章和源代码设计说明文档ppt
35 1
|
8月前
|
JavaScript Java 测试技术
基于springboot+vue.js的多媒体素材库附带文章和源代码设计说明文档ppt
基于springboot+vue.js的多媒体素材库附带文章和源代码设计说明文档ppt
44 1
|
8月前
|
JavaScript Java 测试技术
基于微信平台健身小助手小程序的+ssmt+vue.js附带文章和源代码设计说明文档ppt
基于微信平台健身小助手小程序的+ssmt+vue.js附带文章和源代码设计说明文档ppt
55 2
|
8月前
|
JavaScript Java 测试技术
微信社团小程序ssmt+vue.js附带文章和源代码设计说明文档ppt
微信社团小程序ssmt+vue.js附带文章和源代码设计说明文档ppt
38 1
|
8月前
|
JavaScript Java 测试技术
小程序插画共享平台ssm+vue.js附带文章和源代码设计说明文档ppt
小程序插画共享平台ssm+vue.js附带文章和源代码设计说明文档ppt
40 1