00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "Core/precomp.h"
00019 #include "Display/Display/Generic/pixeldata.h"
00020 #include "API/Display/SurfaceProviders/sprite_subarray_provider.h"
00021 #include "API/Core/System/error.h"
00022 #include "API/Display/SurfaceProviders/sprite2.h"
00023 #include "API/Core/IOData/inputsource.h"
00024 #include "API/Display/Font/font_description.h"
00025
00026 CL_Font_Description::CL_Font_Description(CL_InputSource *input)
00027 : source(NULL)
00028 {
00029 space_len = input->read_int32();
00030 subtract_width = input->read_int32();
00031 letters = input->read_string();
00032
00033 int len = letters.length();
00034 for (int i=0; i<len; i++)
00035 {
00036 letter_providers.push_back(new CL_Sprite2Provider(input));
00037 }
00038 }
00039
00040 CL_Font_Description::CL_Font_Description(
00041 CL_SurfaceProvider *p,
00042 int x, int y,
00043 int *tcols, int num_tcols,
00044 int spacelen,
00045 int subtract_width,
00046 const char *letters)
00047 {
00048
00049
00050 this->source = p;
00051 this->space_len = spacelen;
00052 this->subtract_width = subtract_width;
00053 this->letters = letters;
00054
00055 p->lock();
00056
00057 if (p->get_depth() != 8)
00058 {
00059 p->unlock();
00060 throw CL_Error("Old font method only works on PAL8 images.");
00061 }
00062
00063 unsigned char *surface_data = (unsigned char *) p->get_data();
00064
00065
00066 unsigned int h;
00067 for (h=y; h<p->get_height(); h++)
00068 {
00069 if (surface_data[h*p->get_pitch()+x]==255)
00070 {
00071 h-=y;
00072 break;
00073 }
00074 }
00075
00076
00077 int org_x=x;
00078 int next_line=0;
00079 int pos=0;
00080 unsigned char bogst_nr=0;
00081
00082 bogst_nr=letters[pos];
00083
00084 while (bogst_nr != 0)
00085 {
00086
00087 int b;
00088 int p_width = p->get_width();
00089 for (b=x; b<p_width; b++)
00090 {
00091 if (surface_data[y*p->get_pitch()+b]==254)
00092 {
00093 b-=x;
00094 break;
00095 }
00096 else if (surface_data[y*p->get_pitch()+b]==253)
00097 {
00098 b-=x;
00099 next_line=-1;
00100 break;
00101 }
00102 }
00103
00104 letter_providers.push_back(
00105 new CL_Sprite2Provider(
00106 p,
00107 x, y,
00108 b, h,
00109 tcols, num_tcols));
00110 x+=b+1;
00111
00112 if (next_line)
00113 {
00114 x=org_x;
00115 y+=h+1;
00116 next_line=0;
00117 }
00118
00119 pos++;
00120 bogst_nr=letters[pos];
00121 }
00122
00123 p->unlock();
00124 }
00125
00126 CL_Font_Description::CL_Font_Description(
00127 CL_SurfaceProvider *source,
00128 float trans_limit,
00129 int space_len,
00130 int subtract_width,
00131 const char *letters)
00132 {
00133 this->source = source;
00134 this->space_len = space_len;
00135 this->subtract_width = subtract_width;
00136 this->letters = letters;
00137
00138 int begin=0;
00139 bool prev_trans=true;
00140
00141 CL_PixelData alpha(0, 0, 0, 255, source, 1);
00142
00143 int *opaque_row = new int[alpha.get_width()];
00144 memset(opaque_row, 0, alpha.get_width()*sizeof(int));
00145
00146 int alpha_width = alpha.get_width();
00147 int alpha_height = alpha.get_height();
00148 bool found_opaque = false;
00149 bool found_trans = false;
00150
00151 int cut_top = 0;
00152 int cut_bottom = alpha_height;
00153
00154 for (int y=0; y < alpha_height; y++)
00155 {
00156 bool opaque_line = false;
00157 unsigned char *line = alpha.get_line_pixel(y);
00158 for (int x=0; x < alpha_width; x++)
00159 {
00160 if (line[x] > trans_limit*255)
00161 {
00162 opaque_row[x] = 1;
00163 opaque_line = true;
00164 found_opaque = true;
00165 }
00166 }
00167
00168 if (opaque_line == false)
00169 {
00170 if (found_opaque)
00171 {
00172 cut_bottom--;
00173 found_trans = true;
00174 }
00175 else
00176 cut_top ++;
00177 }
00178 else if (found_trans)
00179 {
00180 found_trans = false;
00181 cut_bottom = alpha_height;
00182 }
00183 }
00184
00185 if (cut_top >= cut_bottom)
00186 throw CL_Error("Font image contained only alpha! (or the alpha clipper is broken)");
00187
00188 for(int x=0; x < alpha_width; x++)
00189 {
00190 if(opaque_row[x] && prev_trans)
00191 {
00192 begin = x;
00193 prev_trans = false;
00194 }
00195 else if (!opaque_row[x] && !prev_trans)
00196 {
00197 letter_providers.push_back(
00198 new CL_SpriteSubarrayProvider(
00199 source,
00200 begin,
00201 cut_top,
00202 x-begin+1,
00203 cut_bottom-cut_top,
00204 1, 1));
00205
00206 prev_trans = true;
00207 }
00208 }
00209
00210 if (!prev_trans)
00211 {
00212 letter_providers.push_back(
00213 new CL_SpriteSubarrayProvider(
00214 source,
00215 begin,
00216 cut_top,
00217 alpha.get_width()-begin,
00218 cut_bottom-cut_top,
00219 1, 1));
00220 }
00221
00222 delete opaque_row;
00223
00224
00225
00226 if(letter_providers.size() != this->letters.size())
00227 {
00228 std::cout <<
00229 "Resourcefile characters: " <<
00230 letter_providers.size() <<
00231 " Imagefile characters: " <<
00232 this->letters.size() <<
00233 std::endl;
00234 }
00235 cl_assert(letter_providers.size() == this->letters.size());
00236 }
00237
00238 void CL_Font_Description::lock()
00239 {
00240 if (source != NULL) source->lock();
00241 }
00242
00243 void CL_Font_Description::unlock()
00244 {
00245 if (source != NULL) source->unlock();
00246 }