📄 fl_file_icon2.cxx
字号:
//
// "$Id: Fl_File_Icon2.cxx,v 1.1.1.1 2003/06/03 22:25:42 agno Exp $"
//
// Fl_File_Icon system icon routines.
//
// KDE icon code donated by Maarten De Boer.
//
// Copyright 1999-2003 by Michael Sweet.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
// USA.
//
// Please report all bugs and problems to "fltk-bugs@fltk.org".
//
// Contents:
//
// Fl_File_Icon::load_fti() - Load an SGI-format FTI file...
// Fl_File_Icon::load_image() - Load an image icon file...
// Fl_File_Icon::load_system_icons() - Load the standard system icons/filetypes.
//
//
// Include necessary header files...
//
#include <stdio.h>
#include <stdlib.h>
#include "flstring.h"
#include <ctype.h>
#include <errno.h>
#include <FL/math.h>
#include <sys/types.h>
#include <sys/stat.h>
#if defined(WIN32) && ! defined(__CYGWIN__)
# include <io.h>
# define F_OK 0
#else
# include <unistd.h>
#endif // WIN32
#include <FL/Fl_File_Icon.H>
#include <FL/Fl_Shared_Image.H>
#include <FL/Fl_Widget.H>
#include <FL/fl_draw.H>
#include <FL/filename.H>
//
// Define missing POSIX/XPG4 macros as needed...
//
#ifndef S_ISDIR
# define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK)
# define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
# define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
# define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
#endif /* !S_ISDIR */
//
// Local functions...
//
static void load_kde_icons(const char *directory);
static void load_kde_mimelnk(const char *filename);
static char *kde_to_fltk_pattern(const char *kdepattern);
static char *get_kde_val(char *str, const char *key);
//
// Local globals...
//
static const char *kdedir = NULL;
//
// 'Fl_File_Icon::load()' - Load an icon file...
//
void
Fl_File_Icon::load(const char *f) // I - File to read from
{
int i; // Load status...
const char *ext; // File extension
ext = fl_filename_ext(f);
if (ext && strcmp(ext, ".fti") == 0)
i = load_fti(f);
else
i = load_image(f);
if (i)
{
Fl::warning("Fl_File_Icon::load(): Unable to load icon file \"%s\".", f);
return;
}
}
//
// 'Fl_File_Icon::load_fti()' - Load an SGI-format FTI file...
//
int // O - 0 on success, non-zero on error
Fl_File_Icon::load_fti(const char *fti) // I - File to read from
{
FILE *fp; // File pointer
int ch; // Current character
char command[255], // Command string ("vertex", etc.)
params[255], // Parameter string ("10.0,20.0", etc.)
*ptr; // Pointer into strings
int outline; // Outline polygon
// Try to open the file...
if ((fp = fopen(fti, "rb")) == NULL)
{
Fl::error("Fl_File_Icon::load_fti(): Unable to open \"%s\" - %s",
fti, strerror(errno));
return -1;
}
// Read the entire file, adding data as needed...
outline = 0;
while ((ch = getc(fp)) != EOF)
{
// Skip whitespace
if (isspace(ch))
continue;
// Skip comments starting with "#"...
if (ch == '#')
{
while ((ch = getc(fp)) != EOF)
if (ch == '\n')
break;
if (ch == EOF)
break;
else
continue;
}
// OK, this character better be a letter...
if (!isalpha(ch))
{
Fl::error("Fl_File_Icon::load_fti(): Expected a letter at file position %ld (saw '%c')",
ftell(fp) - 1, ch);
break;
}
// Scan the command name...
ptr = command;
*ptr++ = ch;
while ((ch = getc(fp)) != EOF)
{
if (ch == '(')
break;
else if (ptr < (command + sizeof(command) - 1))
*ptr++ = ch;
}
*ptr++ = '\0';
// Make sure we stopped on a parenthesis...
if (ch != '(')
{
Fl::error("Fl_File_Icon::load_fti(): Expected a ( at file position %ld (saw '%c')",
ftell(fp) - 1, ch);
break;
}
// Scan the parameters...
ptr = params;
while ((ch = getc(fp)) != EOF)
{
if (ch == ')')
break;
else if (ptr < (params + sizeof(params) - 1))
*ptr++ = ch;
}
*ptr++ = '\0';
// Make sure we stopped on a parenthesis...
if (ch != ')')
{
Fl::error("Fl_File_Icon::load_fti(): Expected a ) at file position %ld (saw '%c')",
ftell(fp) - 1, ch);
break;
}
// Make sure the next character is a semicolon...
if ((ch = getc(fp)) != ';')
{
Fl::error("Fl_File_Icon::load_fti(): Expected a ; at file position %ld (saw '%c')",
ftell(fp) - 1, ch);
break;
}
// Now process the command...
if (strcmp(command, "color") == 0)
{
// Set the color; for negative colors blend the two primaries to
// produce a composite color. Also, the following symbolic color
// names are understood:
//
// name FLTK color
// ------------- ----------
// iconcolor FL_ICON_COLOR; mapped to the icon color in
// Fl_File_Icon::draw()
// shadowcolor FL_DARK3
// outlinecolor FL_BLACK
if (strcmp(params, "iconcolor") == 0)
add_color(FL_ICON_COLOR);
else if (strcmp(params, "shadowcolor") == 0)
add_color(FL_DARK3);
else if (strcmp(params, "outlinecolor") == 0)
add_color(FL_BLACK);
else
{
int c = atoi(params); // Color value
if (c < 0)
{
// Composite color; compute average...
c = -c;
add_color(fl_color_average((Fl_Color)(c >> 4),
(Fl_Color)(c & 15), 0.5f));
}
else
add_color((Fl_Color)c);
}
}
else if (strcmp(command, "bgnline") == 0)
add(LINE);
else if (strcmp(command, "bgnclosedline") == 0)
add(CLOSEDLINE);
else if (strcmp(command, "bgnpolygon") == 0)
add(POLYGON);
else if (strcmp(command, "bgnoutlinepolygon") == 0)
{
add(OUTLINEPOLYGON);
outline = add(0) - data_;
add(0);
}
else if (strcmp(command, "endoutlinepolygon") == 0 && outline)
{
unsigned cval; // Color value
// Set the outline color; see above for valid values...
if (strcmp(params, "iconcolor") == 0)
cval = FL_ICON_COLOR;
else if (strcmp(params, "shadowcolor") == 0)
cval = FL_DARK3;
else if (strcmp(params, "outlinecolor") == 0)
cval = FL_BLACK;
else
{
int c = atoi(params); // Color value
if (c < 0)
{
// Composite color; compute average...
c = -c;
cval = fl_color_average((Fl_Color)(c >> 4), (Fl_Color)(c & 15), 0.5f);
}
else
cval = c;
}
// Store outline color...
data_[outline] = cval >> 16;
data_[outline + 1] = cval;
outline = 0;
add(END);
}
else if (strncmp(command, "end", 3) == 0)
add(END);
else if (strcmp(command, "vertex") == 0)
{
float x, y; // Coordinates of vertex
if (sscanf(params, "%f,%f", &x, &y) != 2)
break;
add_vertex((short)(int)rint(x * 100.0), (short)(int)rint(y * 100.0));
}
else
{
Fl::error("Fl_File_Icon::load_fti(): Unknown command \"%s\" at file position %ld.",
command, ftell(fp) - 1);
break;
}
}
// Close the file and return...
fclose(fp);
#ifdef DEBUG
printf("Icon File \"%s\":\n", fti);
for (int i = 0; i < num_data_; i ++)
printf(" %d,\n", data_[i]);
#endif /* DEBUG */
return 0;
}
//
// 'Fl_File_Icon::load_image()' - Load an image icon file...
//
int // O - 0 on success, non-0 on error
Fl_File_Icon::load_image(const char *ifile) // I - File to read from
{
Fl_Shared_Image *img; // Image file
img = Fl_Shared_Image::get(ifile);
if (!img || !img->count() || !img->w() || !img->h()) return -1;
if (img->count() == 1) {
int x, y; // X & Y in image
int startx; // Starting X coord
Fl_Color c, // Current color
temp; // Temporary color
const uchar *row; // Pointer into image
// Loop through grayscale or RGB image...
for (y = 0, row = (const uchar *)(*(img->data())); y < img->h(); y ++, row += img->ld())
{
for (x = 0, startx = 0, c = (Fl_Color)-1;
x < img->w();
x ++, row += img->d())
{
switch (img->d())
{
case 1 :
temp = fl_rgb_color(row[0], row[0], row[0]);
break;
case 2 :
if (row[1] > 127)
temp = fl_rgb_color(row[0], row[0], row[0]);
else
temp = (Fl_Color)-1;
break;
case 3 :
temp = fl_rgb_color(row[0], row[1], row[2]);
break;
default :
if (row[3] > 127)
temp = fl_rgb_color(row[0], row[1], row[2]);
else
temp = (Fl_Color)-1;
break;
}
if (temp != c)
{
if (x > startx && c != (Fl_Color)-1)
{
add_color(c);
add(POLYGON);
add_vertex(startx * 9000 / img->w() + 1000, 9500 - y * 9000 / img->h());
add_vertex(x * 9000 / img->w() + 1000, 9500 - y * 9000 / img->h());
add_vertex(x * 9000 / img->w() + 1000, 9500 - (y + 1) * 9000 / img->h());
add_vertex(startx * 9000 / img->w() + 1000, 9500 - (y + 1) * 9000 / img->h());
add(END);
}
c = temp;
startx = x;
}
}
if (x > startx && c != (Fl_Color)-1)
{
add_color(c);
add(POLYGON);
add_vertex(startx * 9000 / img->w() + 1000, 9500 - y * 9000 / img->h());
add_vertex(x * 9000 / img->w() + 1000, 9500 - y * 9000 / img->h());
add_vertex(x * 9000 / img->w() + 1000, 9500 - (y + 1) * 9000 / img->h());
add_vertex(startx * 9000 / img->w() + 1000, 9500 - (y + 1) * 9000 / img->h());
add(END);
}
}
} else {
int i, j; // Looping vars
int ch; // Current character
int newch; // New character
int bg; // Background color
char val[16]; // Color value
const char *lineptr, // Pointer into line
*const*ptr; // Pointer into data array
int ncolors, // Number of colors
chars_per_color; // Characters per color
Fl_Color *colors; // Colors
int red, green, blue; // Red, green, and blue values
int x, y; // X & Y in image
int startx; // Starting X coord
// Get the pixmap data...
ptr = img->data();
sscanf(*ptr, "%*d%*d%d%d", &ncolors, &chars_per_color);
colors = new Fl_Color[1 << (chars_per_color * 8)];
// Read the colormap...
memset(colors, 0, sizeof(Fl_Color) << (chars_per_color * 8));
bg = ' ';
ptr ++;
if (ncolors < 0) {
// Read compressed colormap...
const uchar *cmapptr;
ncolors = -ncolors;
for (i = 0, cmapptr = (const uchar *)*ptr; i < ncolors; i ++, cmapptr += 4)
colors[cmapptr[0]] = fl_rgb_color(cmapptr[1], cmapptr[2], cmapptr[3]);
ptr ++;
} else {
for (i = 0; i < ncolors; i ++, ptr ++) {
// Get the color's character
lineptr = *ptr;
ch = *lineptr++;
if (chars_per_color > 1) ch = (ch << 8) | *lineptr++;
// Get the color value...
if ((lineptr = strstr(lineptr, "c ")) == NULL) {
// No color; make this black...
colors[ch] = FL_BLACK;
} else if (lineptr[2] == '#') {
// Read the RGB triplet...
lineptr += 3;
for (j = 0; j < 12; j ++)
if (!isxdigit(lineptr[j]))
break;
switch (j) {
case 0 :
bg = ch;
default :
red = green = blue = 0;
break;
case 3 :
val[0] = lineptr[0];
val[1] = '\0';
red = 255 * strtol(val, NULL, 16) / 15;
val[0] = lineptr[1];
val[1] = '\0';
green = 255 * strtol(val, NULL, 16) / 15;
val[0] = lineptr[2];
val[1] = '\0';
blue = 255 * strtol(val, NULL, 16) / 15;
break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -